From d4569d7bc572ae8f10d7c527cbdfbc9d26cc1ed8 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 6 Aug 2015 18:22:59 +0100 Subject: Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race On a target that is both always in non-stop mode and can do displaced stepping (such as native x86_64 GNU/Linux, with "maint set target-non-stop on"), the step-over-trips-on-watchpoint.exp test sometimes fails like this: (gdb) PASS: gdb.threads/step-over-trips-on-watchpoint.exp: no thread-specific bp: step: thread 1 set scheduler-locking off (gdb) PASS: gdb.threads/step-over-trips-on-watchpoint.exp: no thread-specific bp: step: set scheduler-locking off step -[Switching to Thread 0x7ffff7fc0700 (LWP 11782)] -Hardware watchpoint 4: watch_me - -Old value = 0 -New value = 1 -child_function (arg=0x0) at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c:39 -39 other = 1; /* set thread-specific breakpoint here */ -(gdb) PASS: gdb.threads/step-over-trips-on-watchpoint.exp: no thread-specific bp: step: step +wait_threads () at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c:49 +49 return 1; /* in wait_threads */ +(gdb) FAIL: gdb.threads/step-over-trips-on-watchpoint.exp: no thread-specific bp: step: step Note "scheduler-locking" was set off. The problem is that on such targets, the step-over of thread 2 and the "step" of thread 1 can be set to run simultaneously (since with displaced stepping the breakpoint isn't ever removed from the target), and sometimes, the "step" of thread 1 finishes first, so it'd take another resume to see the watchpoint trigger. Fix this by replacing the wait_threads function with a one-line infinite loop that doesn't call any function, so that the "step" of thread 1 never finishes. gdb/testsuite/ChangeLog: 2015-08-07 Pedro Alves * gdb.threads/step-over-lands-on-breakpoint.c (wait_threads): Delete function. (main): Add alarm. Run an infinite loop instead of calling wait_threads. * gdb.threads/step-over-lands-on-breakpoint.exp (do_test): Change comment. * gdb.threads/step-over-trips-on-watchpoint.c (wait_threads): Delete function. (main): Add alarm. Run an infinite loop instead of calling wait_threads. * gdb.threads/step-over-trips-on-watchpoint.exp (do_test): Change comment. --- .../gdb.threads/step-over-trips-on-watchpoint.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c') diff --git a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c index 6cf97fb8063..34ba079bd39 100644 --- a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c +++ b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c @@ -43,23 +43,26 @@ child_function (void *arg) pthread_exit (NULL); } -static int -wait_threads (void) -{ - return 1; /* in wait_threads */ -} - int main () { int res; long i; + alarm (300); + pthread_barrier_init (&barrier, NULL, 2); res = pthread_create (&child_thread, NULL, child_function, NULL); pthread_barrier_wait (&barrier); - wait_threads (); /* set wait-thread breakpoint here */ + + /* Use an infinite loop with no function calls so that "step" over + this line never finishes before the watchpoint in the other + thread triggers. That can happen if the step-over of thread 2 is + done with displaced stepping on a target that is always in + non-stop mode, as in that case GDB runs both threads + simultaneously. */ + while (1); /* set wait-thread breakpoint here */ pthread_join (child_thread, NULL); -- cgit v1.2.1