This obscure runtime error appears, and I don't kn...
# kotlin-native
n
This obscure runtime error appears, and I don't know why this error is appearing:
Copy code
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
    at ThrowIncorrectDereferenceException (0x28742c)
    at  (0x32cda1)
    at Kotlin_initRuntimeIfNeeded (0x33cd7b)
    at _636f6d2e636861706d616e3a626f6c742d646174612d636f6e73756d6572_kncfun78 (0x32e26c)
    at MQTTClient_run (0x347173)
    at  (0x7fd0e85d86db)
    at clone (0x7fd0e80e9a3f)
    at  ((nil))
All MQTT event handlers with the Paho MQTT Client library ( https://www.eclipse.org/paho/index.php?page=clients/c/index.php ) run in a separate thread (not the main thread), and require the initRuntimeIfNeeded function call.
t
the error message pretty much explains itself, but here is the documenation: https://kotlinlang.org/docs/native-concurrency.html#global-variables-and-singletons
as it says that top level variable needs either
@ThreadLocal
or
@SharedImmutable
on it. unfortunatly, even in the stdlib there is a bunch of fields without this.
The question of course is, where does it come from?
Kotlin_initRuntimeIfNeeded
can be a red herring, it can get in the stacktrace inbetween your own code, if that code is first to run in that thread, so I would try to get debug symbols for
(0x32cda1)
a good guess which part of your code runs first in this probably also works
p
unfortunatly, even in the stdlib there is a bunch of fields without this.
Where?
p
Objects are frozen by default
n
Can lateinit vars cause the issue to occur?
The issue seems to occur at the event handler level:
Copy code
private fun mqttMessageArrived(
    @Suppress("UNUSED_PARAMETER") ctx: COpaquePointer?,
    topic: CPointer<ByteVar>?,
    @Suppress("UNUSED_PARAMETER") topicLength: Int,
    msg: CPointer<MQTTClient_message>?
): Int {
    initRuntimeIfNeeded()
    return true.intValue
}
I have removed everything in the event handler body except for initRuntimeIfNeeded(), and return true.intValue, and the issue still occurs which is weird.
Are top level properties without a backing field one of the elements that can cause the issue to occur?
By the way I am using Coroutines, and not Workers in the Kotlin program.
@Artyom Degtyarev [JB] - The cause of the issue is the initRuntimeIfNeeded function call (there is no top level val or var property that causes the issue), which is needed in the event handler. When commenting out the function call the program will run without the runtime error occurring, however the program exits (likely due to the function call not being made in the event handler) without any error occurring.
t
@Paul Woitaschek good point.. 🤦‍♂️ I seriously misremembered that one
n
Ended up annotating all top level properties that have a backing field with either the ThreadLocal or SharedImmutable annotation, rather than diagnosing each property one by one, which would be time consuming and would have been in a "whack a mole" type situation. Applying the annotations everywhere did the trick (the issue doesn't occur anymore).
The error message that is produced needs to provide information on what is causing the issue, not just say what the error is.
p
Yeah we also just freeze every single class
n
Not every class can be frozen.