Hi there, We see strange crashes on iOS, maybe someone faced with something similar before. We’re no...
s

smbd uknow

over 2 years ago
Hi there, We see strange crashes on iOS, maybe someone faced with something similar before. We’re not sure if it’s connected directly with Kotlin/Native, however we see these stack-traces in Firebase and not able to reproduce the issue locally: GC Timer thread
void kotlin::RepeatedTimer<kotlin::steady_clock>::Run<kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()>(kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()&&) + 4373751076
4

void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(kotlin::ScopedThread::attributes, void (kotlin::RepeatedTimer<kotlin::steady_clock>::*&&)(kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()&&) noexcept, kotlin::RepeatedTimer<kotlin::steady_clock>*&&, kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()&&), kotlin::ScopedThread::attributes, void (kotlin::RepeatedTimer<kotlin::steady_clock>::*)(kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()&&) noexcept, kotlin::RepeatedTimer<kotlin::steady_clock>*, kotlin::gc::internal::GCSchedulerDataWithTimer<kotlin::steady_clock>::GCSchedulerDataWithTimer(kotlin::gc::GCSchedulerConfig&, std::__1::function<void ()>)::'lambda'()> >(void*) + 4373751760
GC thread
std::__1::invoke_result<kotlin::gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(kotlin::mm::ObjectFactory<kotlin::gc::ConcurrentMarkAndSweep>&, kotlin::gc::GCScheduler&)::$_2>::type kotlin::ScopedThread::Run<kotlin::gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(kotlin::mm::ObjectFactory<kotlin::gc::ConcurrentMarkAndSweep>&, kotlin::gc::GCScheduler&)::$_2>(kotlin::ScopedThread::attributes, kotlin::gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(kotlin::mm::ObjectFactory<kotlin::gc::ConcurrentMarkAndSweep>&, kotlin::gc::GCScheduler&)::$_2&&) + 4373763056
4

void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(kotlin::ScopedThread::attributes, kotlin::gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(kotlin::mm::ObjectFactory<kotlin::gc::ConcurrentMarkAndSweep>&, kotlin::gc::GCScheduler&)::$_2&&), kotlin::ScopedThread::attributes, kotlin::gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(kotlin::mm::ObjectFactory<kotlin::gc::ConcurrentMarkAndSweep>&, kotlin::gc::GCScheduler&)::$_2> >(void*) + 4373768160
We use Kotlin 1.7.20
I’m struggling to write tests around `callbackFlow`. I want to ensure that the value emitted from th...
r

rook

almost 4 years ago
I’m struggling to write tests around
callbackFlow
. I want to ensure that the value emitted from the flow matches the value that the callback receives. My problem appears to be that the
ProducerScope
block doesn’t get called until something subscribes to the flow. I thought that using
shareIn
would fix my problem, but it still doesn’t appear to kick off the
ProducerScope
in time
fun someTest() = runBlocking {
  val expected = "someMessage"

  val resultFlow = getCallbackFlow().shareIn(this, SharingStarted.Eagerly, replay = 1)

  sendMessageToTriggerCallback(expected)

  val actual = resultFlow.first()

  assertEquals(expected, actual)
}
After adding some logging, I find that what happens is that first,
sendMessageToTriggerCallback
is invoked, then the callback is registered in the
ProducerScope
, then it suspends indefinitely awaiting the first signal from the
resultFlow
. I’ve tried a lot of variations on this pattern, and I can’t seem to make the
ProducerScope
run without blocking my ability to subsequently trigger sending the message. I’ve tried launching callback flow collection in its own job and sending the message a separate job and yielding between them. I’ve tried leveraging
onSubscription
, but that doesn’t fix the issue either, I get the same execution order as the example above. I’m at a bit of a loss as to how to enforce a deterministic execution order in this test case.