From patchwork Tue Apr 7 12:49:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 6066 Received: (qmail 15345 invoked by alias); 7 Apr 2015 13:30:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 15265 invoked by uid 89); 7 Apr 2015 13:30:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 07 Apr 2015 13:30:47 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t37CoBQ5018807 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 7 Apr 2015 08:50:11 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t37Cnox4022139 for ; Tue, 7 Apr 2015 08:50:10 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH v2 18/23] Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race Date: Tue, 7 Apr 2015 13:49:45 +0100 Message-Id: <1428410990-28560-19-git-send-email-palves@redhat.com> In-Reply-To: <1428410990-28560-1-git-send-email-palves@redhat.com> References: <1428410990-28560-1-git-send-email-palves@redhat.com> 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-04-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-lands-on-breakpoint.c | 17 ++++++++++------- .../gdb.threads/step-over-lands-on-breakpoint.exp | 6 +++--- .../gdb.threads/step-over-trips-on-watchpoint.c | 17 ++++++++++------- .../gdb.threads/step-over-trips-on-watchpoint.exp | 9 ++++----- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.c b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.c index 0a6ed8f..2480164 100644 --- a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.c +++ b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.c @@ -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); diff --git a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp index 4d27059..239aa96 100644 --- a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp +++ b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp @@ -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.*" } } 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 6cf97fb..34ba079 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); diff --git a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp index 3ccceae..a2dc1b9 100644 --- a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp +++ b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp @@ -112,11 +112,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.*" } }