1*b1e83836Smrg import core.memory; 2*b1e83836Smrg import core.sync.condition; 3*b1e83836Smrg import core.sync.mutex; 4*b1e83836Smrg import core.thread; 5*b1e83836Smrg 6*b1e83836Smrg __gshared Condition g_cond; 7*b1e83836Smrg __gshared Mutex g_mutex; 8*b1e83836Smrg __gshared int g_step = 0; 9*b1e83836Smrg 10*b1e83836Smrg class C 11181254a7Smrg { ~this()12181254a7Smrg ~this() 13181254a7Smrg { 14181254a7Smrg import core.stdc.stdlib; 15*b1e83836Smrg abort(); // this gets triggered although the instance always stays referenced 16181254a7Smrg } 17181254a7Smrg } 18181254a7Smrg 19*b1e83836Smrg C c; 20181254a7Smrg this()21181254a7Smrgstatic this() 22181254a7Smrg { 23*b1e83836Smrg c = new C; 24181254a7Smrg } 25181254a7Smrg ~this()26181254a7Smrgstatic ~this() 27181254a7Smrg { 28181254a7Smrg import core.memory; 29*b1e83836Smrg GC.free(cast(void*)c); // free without destruction to avoid triggering abort() 30181254a7Smrg } 31181254a7Smrg test()32*b1e83836Smrgvoid test() 33181254a7Smrg { 34*b1e83836Smrg assert(c !is null); 35*b1e83836Smrg 36*b1e83836Smrg // notify the main thread of the finished initialization 37*b1e83836Smrg synchronized (g_mutex) g_step = 1; 38*b1e83836Smrg g_cond.notifyAll(); 39*b1e83836Smrg 40*b1e83836Smrg // wait until the GC collection is done 41*b1e83836Smrg synchronized (g_mutex) { 42*b1e83836Smrg while (g_step != 2) 43*b1e83836Smrg g_cond.wait(); 44181254a7Smrg } 45*b1e83836Smrg } 46*b1e83836Smrg 47181254a7Smrg main()48181254a7Smrgvoid main() 49181254a7Smrg { 50*b1e83836Smrg g_mutex = new Mutex; 51*b1e83836Smrg g_cond = new Condition(g_mutex); 52181254a7Smrg 53*b1e83836Smrg auto th = new Thread(&test); 54*b1e83836Smrg th.start(); 55*b1e83836Smrg 56*b1e83836Smrg // wait for thread to be fully initialized 57*b1e83836Smrg synchronized (g_mutex) { 58*b1e83836Smrg while (g_step != 1) 59*b1e83836Smrg g_cond.wait(); 60*b1e83836Smrg } 61*b1e83836Smrg 62*b1e83836Smrg // this causes the other thread's C instance to be reaped with the bug present 63*b1e83836Smrg GC.collect(); 64*b1e83836Smrg 65*b1e83836Smrg // allow the thread to shut down 66*b1e83836Smrg synchronized (g_mutex) g_step = 2; 67*b1e83836Smrg g_cond.notifyAll(); 68*b1e83836Smrg 69*b1e83836Smrg th.join(); 70181254a7Smrg } 71