Skip to content

Instantly share code, notes, and snippets.

@defufna
Created September 12, 2019 12:28
Show Gist options
  • Save defufna/be79a3e1690d72246b903147cc0f37dd to your computer and use it in GitHub Desktop.
Save defufna/be79a3e1690d72246b903147cc0f37dd to your computer and use it in GitHub Desktop.
Deadlock on program tremination
package;
import kha.System;
import haxe.ds.Vector;
class Main {
public static function main() {
var v:Vector<Int>;
for (i in 0...8192){
v = new Vector(256);
for(j in 0...v.length){
v[j] = j;
}
}
trace("Exiting....");
}
}
@defufna
Copy link
Author

defufna commented Sep 12, 2019

This sample code will fail to terminate when run on Linux target. The reason is deadlock between main thread and garbage collector thread.
Here is an example stack trace:

Main Thread

#0  0x00007ffff7376aaf in pthread_cond_destroy@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00005555559a2233 in kinc_event_destroy (event=0x555555cad9e0 <sThreadWake+288>) at ../../../../../Kha/Kinc/Backends/System/POSIX/Sources/Kore/Event.cpp:22
#2  0x00005555559baac4 in Kore::Event::destroy (this=0x555555cad9e0 <sThreadWake+288>) at ../../../../../Kha/Kinc/Sources/Kore/Threads/Event.cpp:12
#3  0x00005555559680fe in HxSemaphore::~HxSemaphore (this=0x555555cad9e0 <sThreadWake+288>, __in_chrg=<optimized out>) at ../../../../../Kha/Backends/Kore/khacpp/include/hx/Thread.h:331
#4  0x000055555596c440 in __tcf_0 () at ../../../../../Kha/Backends/Kore/khacpp/src/hx/gc/Immix.cpp:580
#5  0x00007ffff71d4a58 in __run_exit_handlers () from /lib64/libc.so.6
#6  0x00007ffff71d4b9a in exit () from /lib64/libc.so.6
#7  0x00007ffff71bcec2 in __libc_start_main () from /lib64/libc.so.6
#8  0x00005555555e921a in _start ()

GC Thread

#0  0x00007ffff73770ec in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00005555559a22da in kinc_event_wait (event=0x555555cad9e0 <sThreadWake+288>) at ../../../../../Kha/Kinc/Backends/System/POSIX/Sources/Kore/Event.cpp:38
#2  0x00005555559baafc in Kore::Event::wait (this=0x555555cad9e0 <sThreadWake+288>) at ../../../../../Kha/Kinc/Sources/Kore/Threads/Event.cpp:20
#3  0x0000555555968136 in HxSemaphore::Wait (this=0x555555cad9e0 <sThreadWake+288>) at ../../../../../Kha/Backends/Kore/khacpp/include/hx/Thread.h:339
#4  0x000055555597002c in GlobalAllocator::waitForThreadWake (this=0x555559cd9590, inId=3) at ../../../../../Kha/Backends/Kore/khacpp/src/hx/gc/Immix.cpp:4282
#5  0x0000555555970073 in GlobalAllocator::ThreadLoop (this=0x555559cd9590, inId=3) at ../../../../../Kha/Backends/Kore/khacpp/src/hx/gc/Immix.cpp:4293
#6  0x00005555559701e9 in GlobalAllocator::SThreadLoop (inInfo=0x3) at ../../../../../Kha/Backends/Kore/khacpp/src/hx/gc/Immix.cpp:4338
#7  0x00005555559a26cb in ThreadProc (arg=0x555559d11530) at ../../../../../Kha/Kinc/Backends/System/POSIX/Sources/Kore/Thread.cpp:14
#8  0x00007ffff7370408 in start_thread () from /lib64/libpthread.so.0
#9  0x00007ffff729e80f in clone () from /lib64/libc.so.6

What happens is that on main thread termination, all HxSemaphore destructors are called. They end up trying to destroy pthread_cond, which GC threads are waiting on.
I ran this same sample on vanilla Haxe and it doesn't hang there. In default hxcpp implementation pthread_conds are not destroyed on main thread termination, and GC threads are left for OS to clean up.

The simple solution is to comment out HxSemaphore destructor in Backends/Kore/khacpp/include/hx/Thread.h, but I'm not sure if that's the best approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment