andreasmattsson
03/04/2020, 9:58 AMEXC_BAD_ACCESS KERN_INVALID_ADDRESS
and pointing to
(anonymous namespace)::garbageCollect(MemoryState*, bool)
Any suggestions for how to troubleshoot this? It seems to be happening in pretty random places (e.g. the rest of the stack can look quite different from place to place, and analytics events suggests it is happening in a bunch of different views.
A few more (partial) sample stack traces:
Crashed: com.apple.main-thread
0 Deedster 0x1051847e4 (anonymous namespace)::garbageCollect(MemoryState*, bool) + 4313057252
1 Deedster 0x105194b40 ObjHeader* (anonymous namespace)::allocInstance<true>(TypeInfo const*, ObjHeader**) + 4313123648
2 Deedster 0x104a7fbd0 kfun:kotlin.collections.HashMap.hash#internal + 4305697744
3 CoreFoundation 0x193fa9938 -[NSDictionary getObjects:andKeys:count:] + 240
4 CoreFoundation 0x194114064 __NSDictionaryEnumerate + 624
5 Foundation 0x194530f50 _writeJSONObject + 424
6 Foundation 0x194531d1c ___writeJSONArray_block_invoke + 268
7 CoreFoundation 0x19409995c __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 16
0 Deedster 0x100a507e4 (anonymous namespace)::garbageCollect(MemoryState*, bool) + 4381165540
1 Deedster 0x100883658 objc2kotlin.3124 + 4379276888
2 ReactiveSwift 0x102ed9068 $s13ReactiveSwift6SignalC2on5event6failed9completed11interrupted10terminated8disposed5valueACyxq_GyAC5EventOyxq__GcSg_yq_cSgyycSgA3RyxcSgtFyAC8ObserverCyxq__G_AA8LifetimeCtXEfU_yAOcfU_ + 488
3 ReactiveSwift 0x102eea9a4 $s13ReactiveSwift6SignalC2on5event6failed9completed11interrupted10terminated8disposed5valueACyxq_GyAC5EventOyxq__GcSg_yq_cSgyycSgA3RyxcSgtFyAC8ObserverCyxq__G_AA8LifetimeCtXEfU_yAOcfU_TA + 52
4 ReactiveSwift 0x102ebfc28 $s13ReactiveSwift6SignalC8ObserverC4sendyyAC5EventOyxq__GF + 40
5 ReactiveSwift 0x102ed3604 $s13ReactiveSwift6SignalC4Core33_6DF632AE8A9288C3EAD8EFDF3D3AF99ELLC4sendyyAC5EventOyxq__GF + 780
6 ReactiveSwift 0x102ebfc28 $s13ReactiveSwift6SignalC8ObserverC4sendyyAC5EventOyxq__GF + 40
7 ReactiveSwift 0x102ef1354 $s13ReactiveSwift15TransformerCore33_8C2AEE826CBF26B7535B1491D314A4F4LLC5startyAA10Disposable_pAA6SignalC8ObserverCyxq__GAaF_pXEFAJyq0_q1__GAaF_pXEfU_yAH5EventOyxq__GcfU_ + 84
Crashed: com.apple.main-thread
0 Deedster 0x1017e47e4 (anonymous namespace)::garbageCollect(MemoryState*, bool) + 4388997092
1 Deedster 0x1017f490c ReleaseHeapRefStrict + 4389062924
2 Deedster 0x1017f1a64 ReadHeapRefLocked + 4389050980
3 Deedster 0x10114c7d4 kfun:kotlinx.coroutines.CancellableContinuationImpl.<get-state>$kotlinx-coroutines-core()kotlin.Any? + 4382083028
4 Flutter 0x102fb532c (Missing)
5 Flutter 0x102f558fc (Missing)
6 Flutter 0x102fa68dc (Missing)
7 Flutter 0x102f63628 (Missing)
andreasmattsson
03/04/2020, 10:00 AMArtyom Degtyarev [JB]
03/04/2020, 10:30 AMandreasmattsson
03/04/2020, 10:39 AMsvyatoslav.scherbina
03/04/2020, 10:44 AMandreasmattsson
03/04/2020, 10:55 AMclass KotlinJsonMessageCodec : NSObject(), FlutterMessageCodecProtocol {
FlutterMethodCodecProtocal being imported with Cocoapods:
import cocoapods.Flutter.*
Flutter is at the moment the only cocoapod we use. It's been a while since I wrote that code, but I'm pretty sure I was forced somehow to subclass NSObject in order to also implement the FlutterMessageCodecProtocol.andreasmattsson
03/04/2020, 10:57 AMandreasmattsson
03/04/2020, 11:01 AMandreasmattsson
03/04/2020, 11:19 AMimport kotlinx.coroutines.*
import platform.darwin.*
import platform.Foundation.NSThread
import kotlin.coroutines.CoroutineContext
@UseExperimental(InternalCoroutinesApi::class)
private object MainLoopDispatcher : CoroutineDispatcher(), Delay {
override fun dispatch(context: CoroutineContext, block: Runnable) {
if (NSThread.isMainThread()) {
block.run()
} else {
dispatch_async(dispatch_get_main_queue()) {
block.run()
}
}
}
@UseExperimental(ExperimentalCoroutinesApi::class)
@InternalCoroutinesApi
override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) {
with(continuation) {
resumeUndispatched(Unit)
}
}
}
@InternalCoroutinesApi
override fun invokeOnTimeout(timeMillis: Long, block: Runnable): DisposableHandle {
val handle = object : DisposableHandle {
var disposed = false
private set
override fun dispose() {
disposed = true
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) {
if (!handle.disposed) {
block.run()
}
}
return handle
}
}
internal actual val Dispatchers.MainLoop: CoroutineDispatcher get() = MainLoopDispatcher
internal actual val Dispatchers.Flow: CoroutineDispatcher get() = MainLoop
Adapted from here:
https://github.com/Kotlin/kotlinx.coroutines/issues/470#issuecomment-440080970svyatoslav.scherbina
03/04/2020, 11:20 AMDid some more searching in the codebase and I think actually the only cases are protocols from the Flutter Cocoapod that are implemented by Kotlin classes that also subclass NSObject.Can references to these objects potentially leak to other threads?
andreasmattsson
03/04/2020, 11:52 AMandreasmattsson
03/04/2020, 12:17 PMsvyatoslav.scherbina
03/05/2020, 9:20 AMI don’t think I can say with 100% certainty that they can’t leak to other threads though... Would it count as leaking to another thread as only storing a reference to one of these objects on another thread, even though no methods are ever called on it from anyplace else than the main thread?Unfortunately, it would count currently.
Would that be the kind of thing that could cause these kinds of crashes?This is possible. Have you successfully reproduced the crashes on your side?
andreasmattsson
03/05/2020, 9:35 AMsvyatoslav.scherbina
03/05/2020, 9:38 AMandreasmattsson
03/05/2020, 9:42 AMsvyatoslav.scherbina
03/05/2020, 9:44 AMandreasmattsson
03/05/2020, 9:45 AMThread.current.threadDictionary
?svyatoslav.scherbina
03/05/2020, 9:48 AMDo you think we could insulate our Kotin objects by wrapping them in Swift objects that store the references to the Kotlin objectsThis would be enough, even without
Thread.current.threadDictionary
part.andreasmattsson
03/05/2020, 9:50 AMandreasmattsson
03/09/2020, 9:33 AMsvyatoslav.scherbina
03/10/2020, 2:07 PMCan I safely subclass NSObject in my Swift classes that store references to kotlin classesYes, this is totally ok.