Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: gdb/testsuite/gdb.threads/siginfo-threads.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gdb/testsuite/gdb.threads/schedlock.exp ('k') | gdb/testsuite/gdb.threads/siginfo-threads.exp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* This testcase is part of GDB, the GNU debugger. 1 /* This testcase is part of GDB, the GNU debugger.
2 2
3 Copyright 2009-2012 Free Software Foundation, Inc. 3 Copyright 2010-2012 Free Software Foundation, Inc.
4 4
5 This program is free software; you can redistribute it and/or modify 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 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 7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version. 8 (at your option) any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 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/>. */ 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 17
18 #define _GNU_SOURCE 18 #define _GNU_SOURCE
19 #include <pthread.h> 19 #include <pthread.h>
20 #include <stdio.h> 20 #include <stdio.h>
21 #include <limits.h> 21 #include <limits.h>
22 #include <errno.h> 22 #include <errno.h>
23 #include <stdlib.h> 23 #include <stdlib.h>
24 #include <string.h> 24 #include <string.h>
25 #include <assert.h> 25 #include <assert.h>
26 #include <sys/types.h> 26 #include <sys/types.h>
27 #include <signal.h> 27 #include <signal.h>
28 #include <unistd.h> 28 #include <unistd.h>
29 #include <asm/unistd.h> 29 #include <asm/unistd.h>
30 30
31 #define gettid() syscall (__NR_gettid) 31 #define gettid() syscall (__NR_gettid)
32 #define tgkill(tgid, tid, sig) syscall (__NR_tgkill, tgid, tid, sig)
32 33
33 /* Terminate always in the main task, it can lock up with SIGSTOPped GDB 34 /* Terminate always in the main task. It can lock up with SIGSTOPped
34 otherwise. */ 35 GDB otherwise. */
35 #define TIMEOUT (gettid () == getpid() ? 10 : 15) 36 #define TIMEOUT (gettid () == getpid() ? 10 : 15)
36 37
37 static pid_t thread1_tid; 38 static pid_t thread1_tid;
38 static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER; 39 static pthread_cond_t thread1_tid_cond
39 static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_ NP; 40 = PTHREAD_COND_INITIALIZER;
41 static pthread_mutex_t thread1_tid_mutex
42 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
43 static int thread1_sigusr1_hit;
44 static int thread1_sigusr2_hit;
40 45
41 static pid_t thread2_tid; 46 static pid_t thread2_tid;
42 static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER; 47 static pthread_cond_t thread2_tid_cond
43 static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_ NP; 48 = PTHREAD_COND_INITIALIZER;
49 static pthread_mutex_t thread2_tid_mutex
50 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
51 static int thread2_sigusr1_hit;
52 static int thread2_sigusr2_hit;
44 53
45 static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP ; 54 static pthread_mutex_t terminate_mutex
55 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
46 56
47 /* These variables must have lower in-memory addresses than thread1_rwatch and 57 /* Do not use alarm as it would create a ptrace event which would hang
48 thread2_rwatch so that they take their watchpoint slots. */ 58 us up if we are being traced by GDB, which we stopped
59 ourselves. */
49 60
50 static int unused1_rwatch; 61 static void
51 static int unused2_rwatch; 62 timed_mutex_lock (pthread_mutex_t *mutex)
52
53 static volatile int thread1_rwatch;
54 static volatile int thread2_rwatch;
55
56 /* Do not use alarm as it would create a ptrace event which would hang up us if
57 we are being traced by GDB which we stopped ourselves. */
58
59 static void timed_mutex_lock (pthread_mutex_t *mutex)
60 { 63 {
61 int i; 64 int i;
62 struct timespec start, now; 65 struct timespec start, now;
63 66
64 i = clock_gettime (CLOCK_MONOTONIC, &start); 67 i = clock_gettime (CLOCK_MONOTONIC, &start);
65 assert (i == 0); 68 assert (i == 0);
66 69
67 do 70 do
68 { 71 {
69 i = pthread_mutex_trylock (mutex); 72 i = pthread_mutex_trylock (mutex);
70 if (i == 0) 73 if (i == 0)
71 return; 74 return;
72 assert (i == EBUSY); 75 assert (i == EBUSY);
73 76
74 i = clock_gettime (CLOCK_MONOTONIC, &now); 77 i = clock_gettime (CLOCK_MONOTONIC, &now);
75 assert (i == 0); 78 assert (i == 0);
76 assert (now.tv_sec >= start.tv_sec); 79 assert (now.tv_sec >= start.tv_sec);
77 } 80 }
78 while (now.tv_sec - start.tv_sec < TIMEOUT); 81 while (now.tv_sec - start.tv_sec < TIMEOUT);
79 82
80 fprintf (stderr, "Timed out waiting for internal lock!\n"); 83 fprintf (stderr, "Timed out waiting for internal lock!\n");
81 exit (EXIT_FAILURE); 84 exit (EXIT_FAILURE);
82 } 85 }
83 86
87 static void
88 handler (int signo, siginfo_t *siginfo, void *exception)
89 {
90 int *varp;
91
92 assert (siginfo->si_signo == signo);
93 assert (siginfo->si_code == SI_TKILL);
94 assert (siginfo->si_pid == getpid ());
95
96 if (gettid () == thread1_tid)
97 {
98 if (signo == SIGUSR1)
99 varp = &thread1_sigusr1_hit;
100 else if (signo == SIGUSR2)
101 varp = &thread1_sigusr2_hit;
102 else
103 assert (0);
104 }
105 else if (gettid () == thread2_tid)
106 {
107 if (signo == SIGUSR1)
108 varp = &thread2_sigusr1_hit;
109 else if (signo == SIGUSR2)
110 varp = &thread2_sigusr2_hit;
111 else
112 assert (0);
113 }
114 else
115 assert (0);
116
117 if (*varp)
118 {
119 fprintf (stderr, "Signal %d for TID %lu has been already hit!\n", signo,
120 (unsigned long) gettid ());
121 exit (EXIT_FAILURE);
122 }
123 *varp = 1;
124 }
125
84 static void * 126 static void *
85 thread1_func (void *unused) 127 thread1_func (void *unused)
86 { 128 {
87 int i; 129 int i;
88 volatile int rwatch_store;
89 130
90 timed_mutex_lock (&thread1_tid_mutex); 131 timed_mutex_lock (&thread1_tid_mutex);
91 132
92 /* THREAD1_TID_MUTEX must be already locked to avoid race. */ 133 /* THREAD1_TID_MUTEX must be already locked to avoid a race. */
93 thread1_tid = gettid (); 134 thread1_tid = gettid ();
94 135
95 i = pthread_cond_signal (&thread1_tid_cond); 136 i = pthread_cond_signal (&thread1_tid_cond);
96 assert (i == 0); 137 assert (i == 0);
97 i = pthread_mutex_unlock (&thread1_tid_mutex); 138 i = pthread_mutex_unlock (&thread1_tid_mutex);
98 assert (i == 0); 139 assert (i == 0);
99 140
100 rwatch_store = thread1_rwatch; 141 /* Be sure the "t (tracing stop)" test can proceed for both
101 142 threads. */
102 /* Be sure the "t (tracing stop)" test can proceed for both threads. */
103 timed_mutex_lock (&terminate_mutex); 143 timed_mutex_lock (&terminate_mutex);
104 i = pthread_mutex_unlock (&terminate_mutex); 144 i = pthread_mutex_unlock (&terminate_mutex);
105 assert (i == 0); 145 assert (i == 0);
106 146
147 if (!thread1_sigusr1_hit)
148 {
149 fprintf (stderr, "Thread 1 signal SIGUSR1 not hit!\n");
150 exit (EXIT_FAILURE);
151 }
152 if (!thread1_sigusr2_hit)
153 {
154 fprintf (stderr, "Thread 1 signal SIGUSR2 not hit!\n");
155 exit (EXIT_FAILURE);
156 }
157
107 return NULL; 158 return NULL;
108 } 159 }
109 160
110 static void * 161 static void *
111 thread2_func (void *unused) 162 thread2_func (void *unused)
112 { 163 {
113 int i; 164 int i;
114 volatile int rwatch_store;
115 165
116 timed_mutex_lock (&thread2_tid_mutex); 166 timed_mutex_lock (&thread2_tid_mutex);
117 167
118 /* THREAD2_TID_MUTEX must be already locked to avoid race. */ 168 /* THREAD2_TID_MUTEX must be already locked to avoid a race. */
119 thread2_tid = gettid (); 169 thread2_tid = gettid ();
120 170
121 i = pthread_cond_signal (&thread2_tid_cond); 171 i = pthread_cond_signal (&thread2_tid_cond);
122 assert (i == 0); 172 assert (i == 0);
123 i = pthread_mutex_unlock (&thread2_tid_mutex); 173 i = pthread_mutex_unlock (&thread2_tid_mutex);
124 assert (i == 0); 174 assert (i == 0);
125 175
126 rwatch_store = thread2_rwatch; 176 /* Be sure the "t (tracing stop)" test can proceed for both
127 177 threads. */
128 /* Be sure the "t (tracing stop)" test can proceed for both threads. */
129 timed_mutex_lock (&terminate_mutex); 178 timed_mutex_lock (&terminate_mutex);
130 i = pthread_mutex_unlock (&terminate_mutex); 179 i = pthread_mutex_unlock (&terminate_mutex);
131 assert (i == 0); 180 assert (i == 0);
132 181
182 if (!thread2_sigusr1_hit)
183 {
184 fprintf (stderr, "Thread 2 signal SIGUSR1 not hit!\n");
185 exit (EXIT_FAILURE);
186 }
187 if (!thread2_sigusr2_hit)
188 {
189 fprintf (stderr, "Thread 2 signal SIGUSR2 not hit!\n");
190 exit (EXIT_FAILURE);
191 }
192
133 return NULL; 193 return NULL;
134 } 194 }
135 195
136 static const char * 196 static const char *
137 proc_string (const char *filename, const char *line) 197 proc_string (const char *filename, const char *line)
138 { 198 {
139 FILE *f; 199 FILE *f;
140 static char buf[LINE_MAX]; 200 static char buf[LINE_MAX];
141 size_t line_len = strlen (line); 201 size_t line_len = strlen (line);
142 202
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 i = kill (tracer_save, SIGCONT); 319 i = kill (tracer_save, SIGCONT);
260 assert (i == 0); 320 assert (i == 0);
261 } 321 }
262 } 322 }
263 323
264 int 324 int
265 main (int argc, char **argv) 325 main (int argc, char **argv)
266 { 326 {
267 int i; 327 int i;
268 int standalone = 0; 328 int standalone = 0;
329 struct sigaction act;
269 330
270 if (argc == 2 && strcmp (argv[1], "-s") == 0) 331 if (argc == 2 && strcmp (argv[1], "-s") == 0)
271 standalone = 1; 332 standalone = 1;
272 else 333 else
273 assert (argc == 1); 334 assert (argc == 1);
274 335
275 setbuf (stdout, NULL); 336 setbuf (stdout, NULL);
276 337
277 timed_mutex_lock (&thread1_tid_mutex); 338 timed_mutex_lock (&thread1_tid_mutex);
278 timed_mutex_lock (&thread2_tid_mutex); 339 timed_mutex_lock (&thread2_tid_mutex);
279 340
280 timed_mutex_lock (&terminate_mutex); 341 timed_mutex_lock (&terminate_mutex);
281 342
343 errno = 0;
344 memset (&act, 0, sizeof (act));
345 act.sa_sigaction = handler;
346 act.sa_flags = SA_RESTART | SA_SIGINFO;
347 i = sigemptyset (&act.sa_mask);
348 assert_perror (errno);
349 assert (i == 0);
350 i = sigaction (SIGUSR1, &act, NULL);
351 assert_perror (errno);
352 assert (i == 0);
353 i = sigaction (SIGUSR2, &act, NULL);
354 assert_perror (errno);
355 assert (i == 0);
356
282 i = pthread_create (&thread1, NULL, thread1_func, NULL); 357 i = pthread_create (&thread1, NULL, thread1_func, NULL);
283 assert (i == 0); 358 assert (i == 0);
284 359
285 i = pthread_create (&thread2, NULL, thread2_func, NULL); 360 i = pthread_create (&thread2, NULL, thread2_func, NULL);
286 assert (i == 0); 361 assert (i == 0);
287 362
288 if (!standalone) 363 if (!standalone)
289 { 364 {
290 tracer = proc_ulong ("/proc/self/status", "TracerPid:\t"); 365 tracer = proc_ulong ("/proc/self/status", "TracerPid:\t");
291 if (tracer == 0) 366 if (tracer == 0)
(...skipping 15 matching lines...) Expand all
307 382
308 printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer); 383 printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
309 384
310 if (tracer) 385 if (tracer)
311 { 386 {
312 i = kill (tracer, SIGSTOP); 387 i = kill (tracer, SIGSTOP);
313 assert (i == 0); 388 assert (i == 0);
314 state_wait (tracer, "T (stopped)"); 389 state_wait (tracer, "T (stopped)");
315 } 390 }
316 391
317 /* Threads are now waiting at timed_mutex_lock (thread1_tid_mutex) and so 392 /* Threads are now waiting at timed_mutex_lock (thread1_tid_mutex)
318 they could not trigger the watchpoints before GDB gets unstopped later. 393 and so they could not trigger the signals before GDB is unstopped
319 Threads get resumed at pthread_cond_wait below. Use `while' loops for 394 later. Threads get resumed by the pthread_cond_wait below. Use
320 protection against spurious pthread_cond_wait wakeups. */ 395 `while' loops for protection against spurious pthread_cond_wait
396 wakeups. */
321 397
322 printf ("Waiting till the threads initialize their TIDs.\n"); 398 printf ("Waiting till the threads initialize their TIDs.\n");
323 399
324 while (thread1_tid == 0) 400 while (thread1_tid == 0)
325 { 401 {
326 i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex); 402 i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex);
327 assert (i == 0); 403 assert (i == 0);
328 } 404 }
329 405
330 while (thread2_tid == 0) 406 while (thread2_tid == 0)
331 { 407 {
332 i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex); 408 i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex);
333 assert (i == 0); 409 assert (i == 0);
334 } 410 }
335 411
336 printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n", 412 printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n",
337 (unsigned long) thread1_tid, (unsigned long) thread2_tid, 413 (unsigned long) thread1_tid, (unsigned long) thread2_tid,
338 (unsigned long) getpid ()); 414 (unsigned long) getpid ());
339 415
340 printf ("Waiting till the threads get trapped by the watchpoints.\n"); 416 errno = 0;
417 i = tgkill (getpid (), thread1_tid, SIGUSR1);
418 assert_perror (errno);
419 assert (i == 0);
420 i = tgkill (getpid (), thread1_tid, SIGUSR2);
421 assert_perror (errno);
422 assert (i == 0);
423 i = tgkill (getpid (), thread2_tid, SIGUSR1);
424 assert_perror (errno);
425 assert (i == 0);
426 i = tgkill (getpid (), thread2_tid, SIGUSR2);
427 assert_perror (errno);
428 assert (i == 0);
429
430 printf ("Waiting till the threads are trapped by the signals.\n");
341 431
342 if (tracer) 432 if (tracer)
343 { 433 {
344 /* s390x-unknown-linux-gnu will fail with "R (running)". */ 434 /* s390x-unknown-linux-gnu will fail with "R (running)". */
345 435
346 state_wait (thread1_tid, "t (tracing stop)"); 436 state_wait (thread1_tid, "t (tracing stop)");
347 437
348 state_wait (thread2_tid, "t (tracing stop)"); 438 state_wait (thread2_tid, "t (tracing stop)");
349 } 439 }
350 440
351 cleanup (); 441 cleanup ();
352 442
353 printf ("Joining the threads.\n"); 443 printf ("Joining the threads.\n");
354 444
355 i = pthread_mutex_unlock (&terminate_mutex); 445 i = pthread_mutex_unlock (&terminate_mutex);
356 assert (i == 0); 446 assert (i == 0);
357 447
358 i = pthread_join (thread1, NULL); 448 i = pthread_join (thread1, NULL);
359 assert (i == 0); 449 assert (i == 0);
360 450
361 i = pthread_join (thread2, NULL); 451 i = pthread_join (thread2, NULL);
362 assert (i == 0); 452 assert (i == 0);
363 453
364 printf ("Exiting.\n"); /* break-at-exit */ 454 printf ("Exiting.\n"); /* break-at-exit */
365 455
366 /* Just prevent compiler `warning: unusedX_rwatch defined but not used'. */
367 unused1_rwatch = 1;
368 unused2_rwatch = 2;
369
370 return EXIT_SUCCESS; 456 return EXIT_SUCCESS;
371 } 457 }
OLDNEW
« no previous file with comments | « gdb/testsuite/gdb.threads/schedlock.exp ('k') | gdb/testsuite/gdb.threads/siginfo-threads.exp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698