1 //===-- main.cpp ------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // This test is intended to create a situation in which one thread will exit 11 // while a the debugger is stepping in another thread. 12 13 #include <pthread.h> 14 #include <unistd.h> 15 16 // Note that although hogging the CPU while waiting for a variable to change 17 // would be terrible in production code, it's great for testing since it 18 // avoids a lot of messy context switching to get multiple threads synchronized. 19 #define do_nothing() 20 21 #define pseudo_barrier_wait(bar) \ 22 --bar; \ 23 while (bar > 0) \ 24 do_nothing(); 25 26 #define pseudo_barrier_init(bar, count) (bar = count) 27 28 // A barrier to synchronize thread start. 29 volatile int g_barrier; 30 31 volatile int g_thread_exited = 0; 32 33 volatile int g_test = 0; 34 35 void * 36 step_thread_func (void *input) 37 { 38 // Wait until both threads are started. 39 pseudo_barrier_wait(g_barrier); 40 41 g_test = 0; // Set breakpoint here 42 43 while (!g_thread_exited) 44 g_test++; 45 46 // One more time to provide a continue point 47 g_test++; // Continue from here 48 49 // Return 50 return NULL; 51 } 52 53 void * 54 exit_thread_func (void *input) 55 { 56 // Wait until both threads are started. 57 pseudo_barrier_wait(g_barrier); 58 59 // Wait until the other thread is stepping. 60 while (g_test == 0) 61 do_nothing(); 62 63 // Return 64 return NULL; 65 } 66 67 int main () 68 { 69 pthread_t thread_1; 70 pthread_t thread_2; 71 72 // Synchronize thread start so that doesn't happen during stepping. 73 pseudo_barrier_init(g_barrier, 2); 74 75 // Create a thread to hit the breakpoint. 76 pthread_create (&thread_1, NULL, step_thread_func, NULL); 77 78 // Create a thread to exit while we're stepping. 79 pthread_create (&thread_2, NULL, exit_thread_func, NULL); 80 81 // Wait for the exit thread to finish. 82 pthread_join(thread_2, NULL); 83 84 // Let the stepping thread know the other thread is gone. 85 g_thread_exited = 1; 86 87 // Wait for the stepping thread to finish. 88 pthread_join(thread_1, NULL); 89 90 return 0; 91 } 92