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