Kotlin/Native - illegal attempt to access non-shared <object>
Asked Answered
O

1

5

In my app, I have two classes, a swift class inheriting from a kotlin class:

Swift class:

public class MySensor: RawSensor

    [...]

    public override func notifyChanged(values: KotlinFloatArray) {
      super.notifyChanged(values: values)
    }
}

Kotlin class:

package com.mycompany.myapp.mypackage.sensors.rawsensors

import com.mycompany.myapp.mypackage.util.Observable

abstract class RawSensor : Observable() {

  protected abstract val sensorDataType: RawSensorData.SensorDataType

  abstract val currentTime: Long

  protected open fun notifyChanged(values: FloatArray) {
      notifyObservers(RawSensorData(values, sensorDataType, currentTime))
  }

  abstract fun start()

  abstract fun stop()
}

When super.notifyChanged(values: values) is called, the app crashes with the following error:

Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@83cb47c8 from other thread
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@83cb4788 from other thread
        at 0   MyNativeFramework                   0x00000001048815dc kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 84
        at 1   MyNativeFramework                   0x00000001048805f8 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 84
        at 2   MyNativeFramework                   0x00000001048ac630 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 84
        at 3   MyNativeFramework                   0x00000001048ad7bc ThrowIllegalObjectSharingException + 496
        at 4   MyNativeFramework                   0x0000000104a6f1a0 _ZNK16KRefSharedHolder3refEv + 240
        at 5   MyNativeFramework                   0x0000000104a6eeb0 -[KotlinBase retain] + 52
        at 6   libobjc.A.dylib                     0x00000001aad36288 objc_retain + 88
        at 7   PositionKit                         0x000000010449454c $s11PositionKit21MySensorC13notifyChanged6valuesySo19MyNativeLibraryKotlinFloatArrayC_tFTo + 56
        at 8   PositionKit                         0x0000000104493fa0 $s11PositionKit21MySensorC5startyyFySo19CMAccelerometerDataCSg_s5Error_pSgtcfU_ + 796
        at 9   PositionKit                         0x00000001044941ec $sSo19CMAccelerometerDataCSgs5Error_pSgIeggg_ACSo7NSErrorCSgIeyByy_TR + 152
        at 10  CoreMotion                          0x00000001b7c44a8c CLClientCreateIso6709Notation + 30848
        at 11  Foundation                          0x00000001ab3d1c60 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1170528
        at 12  Foundation                          0x00000001ab2d37e8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 129000
        at 13  Foundation                          0x00000001ab3d3fbc 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1179580
        at 14  Foundation                          0x00000001ab2d3464 672CF0CB-4951-3B91-89DF-55E953AEA00F + 128100
        at 15  Foundation                          0x00000001ab3d49e8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1182184
        at 16  Foundation                          0x00000001ab3d44a8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1180840
        at 17  libdispatch.dylib                   0x0000000104f59a48 _dispatch_block_async_invoke2 + 144
        at 18  libdispatch.dylib                   0x0000000104f4b2a8 _dispatch_client_callout + 20
        at 19  libdispatch.dylib                   0x0000000104f5935c _dispatch_main_queue_callback_4CF + 1376
        at 20  CoreFoundation                      0x00000001aaf7ce20 97285ACB-7B21-393A-ABF6-03F1DBB5D2A2 + 712224
        at 21  CoreFoundation                      0x00000001aaf77b7c 97285ACB-7B21-393A-ABF6-03F1DBB5D2A2 + 691068
        at 22  CoreFoundation                      0x00000001aaf77098 CFRunLoopRunSpecific + 480
        at 23  GraphicsServices                    0x00000001b50e1534 GSEventRunModal + 108
        at 24  UIKitCore                           0x00000001af0977ac UIApplicationMain + 1940
        at 25  MyTestApp                           0x00000001044383a4 main + 76
        at 26  libdyld.dylib                       0x00000001aadf6f30 0DC9A4BA-C3E8-3487-99DB-1B5C86597AF5 + 3888
        at 0   MyNativeFramework                   0x00000001048815dc kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 84
        at 1   MyNativeFramework                   0x00000001048805f8 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 84
        at 2   MyNativeFramework                   0x00000001048ac630 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 84
        at 3   MyNativeFramework                   0x00000001048ad7bc ThrowIllegalObjectSharingException + 496
        at 4   MyNativeFramework                   x0000000104a6f1a0 _ZNK16KRefSharedHolder3refEv + 240
        at 5   MyNativeFramework                   0x0000000104a6eff4 -[KotlinBase release] + 48
        at 6   libobjc.A.dylib                     0x00000001aad36408 objc_release + 136
        at 7   PositionKit                         0x00000001044967e8 $s11PositionKit17MySensorC5startyyFySo14CMDeviceMotionCSg_s5Error_pSgtcfU_ + 684(lldb)

(names have been changed to protect closed source code)

What am I doing wrong? Do I have to somehow mark the float array as shared? I've read up on data freezing in Kotlin/Native but that only seems to apply to objects within the kotlin context.

Oxide answered 7/11, 2019 at 17:19 Comment(0)
E
8

You have two exceptions here. The second one will be fixed in upcoming Kotlin 1.3.60 release.

The first one is likely caused by main thread accessing Kotlin object created on a background thread with an object expression (it could be sensorDataType), it could be MySensor instance. Freezing this object should help.

Estren answered 8/11, 2019 at 9:3 Comment(5)
Thank you for your answer, I think it guided me in the right direction. sensorDataType is an enum, so that does make sense. I noticed I had failed to override two properties on the Swift side, however doing that did not fix the issue. How do I go about freezing an object? This tells me I should be able to call freeze() on any object, but trying to call it results in Unresolved reference: freeze even with an import on kotlin.native.concurrent.*Oxide
The fact that sensorDataType is an enum gave me the idea that I was wrong in the details. An object requiring freezing is not sensorDataType but it is MySensor instance itself. kotlin.native.concurrent.* is Native-only, so it is available only in iOS source set of your project.Estren
Any direction on how to freeze would be helpful!Dasher
You don't need to freeze anything anymore, since there is the new memory manager in Kotlin/Native, and it is enabled by default since Kotlin 1.7.20. See more details here: kotlinlang.org/docs/…Estren
What is meant by freezing an object?Girand

© 2022 - 2024 — McMap. All rights reserved.