1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2009-2017 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include <pthread.h> 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <signal.h> 22 23 unsigned int args[2]; 24 25 pthread_barrier_t barrier; 26 pthread_t child_thread_2, child_thread_3; 27 28 void 29 handler (int signo) 30 { 31 /* so that thread 3 is sure to run, in case the bug is present. */ 32 usleep (10); 33 } 34 35 void 36 callme (void) 37 { 38 } 39 40 void * 41 child_function_3 (void *arg) 42 { 43 int my_number = (long) arg; 44 volatile int *myp = (int *) &args[my_number]; 45 46 pthread_barrier_wait (&barrier); 47 48 while (*myp > 0) 49 { 50 (*myp) ++; /* set breakpoint child_two here */ 51 callme (); 52 } 53 54 pthread_exit (NULL); 55 } 56 57 void * 58 child_function_2 (void *arg) 59 { 60 int my_number = (long) arg; 61 volatile int *myp = (int *) &args[my_number]; 62 63 pthread_barrier_wait (&barrier); 64 65 while (*myp > 0) 66 { 67 (*myp) ++; 68 callme (); /* set breakpoint child_one here */ 69 } 70 71 *myp = 1; 72 while (*myp > 0) 73 { 74 (*myp) ++; 75 callme (); 76 } 77 78 pthread_exit (NULL); 79 } 80 81 82 int 83 main () 84 { 85 int res; 86 long i; 87 88 signal (SIGUSR1, handler); 89 90 /* Call these early so that PLTs for these are resolved soon, 91 instead of in the threads. RTLD_NOW should work as well. */ 92 usleep (0); 93 pthread_barrier_init (&barrier, NULL, 1); 94 pthread_barrier_wait (&barrier); 95 96 pthread_barrier_init (&barrier, NULL, 2); 97 98 i = 0; 99 args[i] = 1; 100 res = pthread_create (&child_thread_2, 101 NULL, child_function_2, (void *) i); 102 pthread_barrier_wait (&barrier); 103 callme (); /* set wait-thread-2 breakpoint here */ 104 105 i = 1; 106 args[i] = 1; 107 res = pthread_create (&child_thread_3, 108 NULL, child_function_3, (void *) i); 109 pthread_barrier_wait (&barrier); 110 callme (); /* set wait-thread-3 breakpoint here */ 111 112 pthread_kill (child_thread_2, SIGUSR1); 113 114 pthread_join (child_thread_2, NULL); 115 pthread_join (child_thread_3, NULL); 116 117 exit(EXIT_SUCCESS); 118 } 119