1 // This test is intended to create a situation in which one thread will exit 2 // while the debugger is stepping in another thread. 3 4 #include "pseudo_barrier.h" 5 #include <thread> 6 7 #define do_nothing() 8 9 // A barrier to synchronize thread start. 10 pseudo_barrier_t g_barrier; 11 12 volatile int g_thread_exited = 0; 13 14 volatile int g_test = 0; 15 16 void * step_thread_func()17step_thread_func () 18 { 19 // Wait until both threads are started. 20 pseudo_barrier_wait(g_barrier); 21 22 g_test = 0; // Set breakpoint here 23 24 while (!g_thread_exited) 25 g_test++; 26 27 // One more time to provide a continue point 28 g_test++; // Continue from here 29 30 // Return 31 return NULL; 32 } 33 34 void * exit_thread_func()35exit_thread_func () 36 { 37 // Wait until both threads are started. 38 pseudo_barrier_wait(g_barrier); 39 40 // Wait until the other thread is stepping. 41 while (g_test == 0) 42 do_nothing(); 43 44 // Return 45 return NULL; 46 } 47 main()48int main () 49 { 50 // Synchronize thread start so that doesn't happen during stepping. 51 pseudo_barrier_init(g_barrier, 2); 52 53 // Create a thread to hit the breakpoint. 54 std::thread thread_1(step_thread_func); 55 56 // Create a thread to exit while we're stepping. 57 std::thread thread_2(exit_thread_func); 58 59 // Wait for the exit thread to finish. 60 thread_2.join(); 61 62 // Let the stepping thread know the other thread is gone. 63 g_thread_exited = 1; 64 65 // Wait for the stepping thread to finish. 66 thread_1.join(); 67 68 return 0; 69 } 70