Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race
authorPedro Alves <palves@redhat.com>
Thu, 6 Aug 2015 17:22:59 +0000 (18:22 +0100)
committerPedro Alves <palves@redhat.com>
Fri, 7 Aug 2015 16:26:21 +0000 (17:26 +0100)
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  <palves@redhat.com>

* 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/testsuite/ChangeLog
gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.c
gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp
gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.c
gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp

index 5e4d5e7b29a228996844e8b866e7a62c6b9c5a8e..db7538a769e832f7b8b5f5cc97f507583c79ecfc 100644 (file)
@@ -1,3 +1,18 @@
+2015-08-07  Pedro Alves  <palves@redhat.com>
+
+       * 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.
+
 2015-08-07  Pedro Alves  <palves@redhat.com>
 
        * gdb.base/checkpoint-ns.exp: New file.
index 0a6ed8f04b90e79fd1f325a1a2d9c164619ef19a..248016420e09859c84d37a2f021aa2d1bf8e17ab 100644 (file)
@@ -41,23 +41,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 breakpoint 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);
 
index 52b59ec438e3fbe88832d720ea4b6ad997c07a8f..b38f23bfad3a70b7b54fe6b88938de62483f3626 100644 (file)
@@ -59,9 +59,9 @@ proc do_test {displaced command} {
        gdb_test_no_output "set scheduler-locking off"
 
        # Thread 2 is still stopped at a breakpoint that needs to be
-       # stepped over before proceeding thread 1.  However, right
-       # where the step-over lands there's another breakpoint
-       # installed, which should trap and be reported to the user.
+       # stepped over.  However, right where the step-over lands
+       # there's another breakpoint installed, which should trap and
+       # be reported to the user.
        gdb_test "$command" "step-over here.*"
     }
 }
index 6cf97fb806325cb222f0bcd5f38028e5a8c213ca..34ba079bd3933367d5b0f4e640ad4f97ecbc0a3a 100644 (file)
@@ -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);
 
index 89b66e55de65d0d403b818267ed90203ecb6f9d5..7e27f97d6293b03c1570030c0663bf8dede070ab 100644 (file)
@@ -115,11 +115,10 @@ proc do_test { displaced with_bp } {
                gdb_test "thread 1" "Switching to .*"
                gdb_test_no_output "set scheduler-locking off"
 
-               # Thread 2 is still stopped at a breakpoint that needs to be
-               # stepped over before proceeding thread 1.  However, the
-               # instruction that is under the breakpoint triggers a
-               # watchpoint, which should trap and be reported to the
-               # user.
+               # Thread 2 is still stopped at a breakpoint that needs
+               # to be stepped over.  However, the instruction that
+               # is under the breakpoint triggers a watchpoint, which
+               # should trap and be reported to the user.
                gdb_test "$command" "Hardware watchpoint.*: watch_me.*New value = 1.*"
            }
        }