Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eager initialization and start of a Worker by defaultStateRunner global variable might lead to a Kotlin runtime initialization race with main thread #70

Open
nikolaykasyanov opened this issue Oct 13, 2021 · 0 comments

Comments

@nikolaykasyanov
Copy link

nikolaykasyanov commented Oct 13, 2021

Here's what I believe is happening:

  • Kotlin code is accessed on main thread for the first time, triggering runtime initialization
  • Runtime initialization initializes globals, among these is defaultStateRunner that creates a Worker internally
  • One of the first things Worker does is initializing runtime on its thread
  • 💥

Unfortunately it's not happening always, I noticed that changing dependency graph might trigger or make it stop happening, which can be explained by changes to the initialization code (and hence the order of global initialization) in the resulting binary effected by dependency graph changes.

There's a known issue in Kotlin related to top-level property initialization thread safety: https://youtrack.jetbrains.com/issue/KT-46771.

Environment:

  • Various iOS versions
  • Kotlin 1.5.21, 1.5.31
  • Stately version 1.1.10-a1

In my case it was a ktor's global that triggered the crash, below are (redacted) stacktraces:

Crashed thread:

#0	0x0000000107a91de8 in isEmpty [inlined] at /opt/buildAgent/work/c5a36d4d82b914cf/kotlin/libraries/stdlib/src/kotlin/text/Strings.kt:296
#1	0x0000000107a91de8 in kfun:kotlinx.cinterop#<get-cstr>__at__kotlin.String(){}kotlinx.cinterop.CValues<kotlinx.cinterop.ByteVarOf<kotlin.Byte>> at /opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt:415
#2	0x0000000107ed0330 in kfun:io.ktor.utils.io.charsets.CharsetImpl.<init>#internal at /Users/administrator/Documents/agent/work/49d4a482a8522285/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt:26
#3	0x0000000107ed0158 in kfun:io.ktor.utils.io.charsets.Charsets#<init>(){} at /Users/administrator/Documents/agent/work/49d4a482a8522285/ktor-io/posix/src/io/ktor/utils/io/charsets/CharsetNative.kt:383
#4	0x00000001083b78b8 in InitSingletonStrict ()
#5	0x0000000108158f68 in ___lldb_unnamed_symbol457$$RedactedFrameworkName ()
#6	0x00000001083c2418 in Kotlin_initRuntimeIfNeeded ()
#7	0x00000001083c47ac in (anonymous namespace)::workerRoutine(void*) ()
#8	0x0000000231f212c0 in _pthread_body ()
#9	0x0000000231f21220 in _pthread_start ()
#10	0x0000000231f24cdc in thread_start ()

Main thread at the moment (only top calls):

#0	0x0000000231e9dea8 in __bsdthread_create ()
#1	0x0000000231f21770 in _pthread_create ()
#2	0x0000000107ab3f84 in start [inlined] at /opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Worker.kt:42
#3	0x0000000107ab3f50 in kfun:kotlin.native.concurrent.Worker.Companion#start$default(kotlin.Boolean;kotlin.String?;kotlin.Int){}kotlin.native.concurrent.Worker at /opt/buildAgent/work/c5a36d4d82b914cf/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Worker.kt:41
#4	0x00000001081388e0 in ___lldb_unnamed_symbol321$$RedactedFrameworkName ()
#5	0x00000001083c23f4 in Kotlin_initRuntimeIfNeeded ()
#6	0x00000001082d168c in ___lldb_unnamed_symbol2320$$RedactedFrameworkName ()
....

The hypothesis is that the crashed thread was trying to access platformUtf16 before it was initialized by the main thread.

Kotlin slack private thread: https://kotlinlang.slack.com/archives/GQG00BACW/p1633245145058600

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant