Hi qemu-devel, We've been having crash reports in QEMU 2.12 on the anroid emulator in SwitchToFiber that make it look like the coroutine or fiber getting switched to is null.
Thread 16 (id: 0x13bc) CRASHED [EXCEPTION_ACCESS_VIOLATION_READ @ 0x00000010 ] Stack Quality84%Show frame trust levels 0x00007ffc1e694d90(KERNELBASE.dll+ 0x00064d90)SwitchToFiber 0x017b4b78(qemu-system-x86_64.exe -coroutine-win32.c:59)qemu_coroutine_switch 0x017b3db6(qemu-system-x86_64.exe -qemu-coroutine.c:161)qemu_aio_coroutine_enter 0x017a0a0f(qemu-system-x86_64.exe -async.c:496)aio_co_enter 0x005b76b2(qemu-system-x86_64.exe -block-backend.c:1364)blk_aio_prwv 0x005b77e7(qemu-system-x86_64.exe -block-backend.c:1458)blk_aio_preadv 0x00493b31(qemu-system-x86_64.exe -virtio-blk.c:372)virtio_blk_submit_multireq 0x00494331(qemu-system-x86_64.exe -virtio-blk.c:620)virtio_blk_handle_vq 0x017a2aca(qemu-system-x86_64.exe -aio-win32.c:308)aio_dispatch_handlers 0x017a324e(qemu-system-x86_64.exe -aio-win32.c:355)aio_dispatch 0x017a02f8(qemu-system-x86_64.exe -async.c:261)aio_ctx_dispatch 0x017c64b8(qemu-system-x86_64.exe -gmain.c:3072)g_main_context_dispatch 0x017a2451(qemu-system-x86_64.exe -main-loop.c:496)os_host_main_loop_wait 0x017a2807(qemu-system-x86_64.exe -main-loop.c:530)main_loop_wait 0x00415016(qemu-system-x86_64.exe -vl.c:2172)main_impl 0x00415ad9(qemu-system-x86_64.exe -vl.c:3332)run_qemu_main 0x00415b54(qemu-system-x86_64.exe -main.cpp:586)enter_qemu_main_loop 0x6675de4b(Qt5Core.dll -qthread_win.cpp:391)QThreadPrivate::start 0x00007ffc1fbbaa95(msvcrt.dll+ 0x0003aa95)beginthreadex 0x00007ffc1fbbab6b(msvcrt.dll+ 0x0003ab6b)endthreadex 0x00007ffc1feb3033(kernel32.dll+ 0x00013033)BaseThreadInitThunk 0x00007ffc22161460(ntdll.dll+ 0x00071460) 0x00007ffc1e71bf0f(KERNELBASE.dll+ 0x000ebf0f)TerminateProcessOnMemoryExhaustion Backing up the data flow a bit says that in qemu_aio_coroutine_enter, Coroutine* to = QSIMPLEQ_FIRST(&pending); and |to| is dererenced a few times before the call to qemu_coroutine_switch: to->caller = from; to->ctx = ctx; smp_wmb(); qemu_coroutine_switch(from, to, COROUTINE_ENTER) |to| is just some number so I don't think that is null. But what about |to->fiber|? In coroutine-win32.c that's what's actually passed to SwitchToFiber anyway: CoroutineWin32 *to = DO_UPCAST(CoroutineWin32, base, to_); // just arithmetic and it is a 64 bit process so I highly doubt anything is under/overflowing ... SwitchToFiber(to->fiber); // crash I also see that the following functions affect fiber: Coroutine *qemu_coroutine_new(void) { const size_t stack_size = COROUTINE_STACK_SIZE; CoroutineWin32 *co; co = g_malloc0(sizeof(*co)); co->fiber = CreateFiber(stack_size, coroutine_trampoline, &co->base); return &co->base; } void qemu_coroutine_delete(Coroutine *co_) { CoroutineWin32 *co = DO_UPCAST(CoroutineWin32, base, co_); DeleteFiber(co->fiber); g_free(co); } Coroutine *qemu_coroutine_self(void) { Coroutine* res = QEMU_THREAD_LOCAL_GET(current); if (!res) { CoroutineWin32* pleader = QEMU_THREAD_LOCAL_GET_PTR(leader); res = &pleader->base; QEMU_THREAD_LOCAL_SET(current, res); pleader->fiber = ConvertThreadToFiber(NULL); } return res; } which makes me think it could be a race condition with any of these three functions or a failure in ConvertThreadToFiber. How likely is it that it is a race condition? Or that the fiber was never initialized to begin with. Frank