From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22152 invoked by alias); 9 Sep 2015 10:36:11 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 21965 invoked by uid 89); 9 Sep 2015 10:36:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL,BAYES_05,KAM_LAZY_DOMAIN_SECURITY,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 09 Sep 2015 10:35:53 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 09 Sep 2015 03:35:17 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 09 Sep 2015 03:35:15 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t89AZDk3004759; Wed, 9 Sep 2015 11:35:14 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id t89AZDZa000619; Wed, 9 Sep 2015 12:35:13 +0200 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id t89AZDi8000615; Wed, 9 Sep 2015 12:35:13 +0200 From: Markus Metzger To: palves@redhat.com Cc: gdb-patches@sourceware.org Subject: [PATCH 13/17] btrace: non-stop Date: Wed, 09 Sep 2015 10:36:00 -0000 Message-Id: <1441794909-32718-14-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1441794909-32718-1-git-send-email-markus.t.metzger@intel.com> References: <1441794909-32718-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg00121.txt.bz2 Support non-stop mode in record btrace. 2015-09-09 Markus Metzger gdb/ * record-btrace.c (record_btrace_open): Remove non_stop check. * NEWS: Announce that record btrace supports non-stop mode. testsuite/ * gdb.btrace/non-stop.c: New. * gdb.btrace/non-stop.exp: New. --- gdb/NEWS | 2 + gdb/record-btrace.c | 3 - gdb/testsuite/gdb.btrace/non-stop.c | 45 ++++++ gdb/testsuite/gdb.btrace/non-stop.exp | 264 ++++++++++++++++++++++++++++++++++ 4 files changed, 311 insertions(+), 3 deletions(-) create mode 100644 gdb/testsuite/gdb.btrace/non-stop.c create mode 100644 gdb/testsuite/gdb.btrace/non-stop.exp diff --git a/gdb/NEWS b/gdb/NEWS index 0cf51e1..1fa1862 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,8 @@ *** Changes since GDB 7.10 +* Record btrace now supports non-stop mode. + * Support for tracepoints on aarch64-linux was added in GDBserver. * The 'record instruction-history' command now indicates speculative execution diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 119bf92..f3e6abe 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -216,9 +216,6 @@ record_btrace_open (const char *args, int from_tty) if (!target_has_execution) error (_("The program is not being run.")); - if (non_stop) - error (_("Record btrace can't debug inferior in non-stop mode.")); - gdb_assert (record_btrace_thread_observer == NULL); disable_chain = make_cleanup (null_cleanup, NULL); diff --git a/gdb/testsuite/gdb.btrace/non-stop.c b/gdb/testsuite/gdb.btrace/non-stop.c new file mode 100644 index 0000000..2fc8dfb --- /dev/null +++ b/gdb/testsuite/gdb.btrace/non-stop.c @@ -0,0 +1,45 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +static int global; + +static void * +test (void *arg) +{ + unsigned int i; + + i = 0; /* bp.1 */ + for (; i < 10; ++i) global += i; /* loop */ + + return arg; /* bp.2 */ +} + +int +main (void) +{ + pthread_t th; + + pthread_create (&th, NULL, test, NULL); + + test (NULL); + + pthread_join (th, NULL); + + return 0; /* bp.3 */ +} diff --git a/gdb/testsuite/gdb.btrace/non-stop.exp b/gdb/testsuite/gdb.btrace/non-stop.exp new file mode 100644 index 0000000..ee7d1b6 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/non-stop.exp @@ -0,0 +1,264 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2015 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# check for btrace support +if { [skip_btrace_tests] } { return -1 } + + +# start inferior +standard_testfile +if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debug}] != "" } { + return -1 +} +clean_restart $testfile + +gdb_test_no_output "set non-stop on" + +if ![runto_main] { + return -1 +} + +# set up breakpoints +set bp_1 [gdb_get_line_number "bp.1" $srcfile] +set bp_2 [gdb_get_line_number "bp.2" $srcfile] +set bp_3 [gdb_get_line_number "bp.3" $srcfile] + +gdb_breakpoint $bp_1 +gdb_breakpoint $bp_2 + +# get the line number containing most of the trace +set loop [gdb_get_line_number "loop" $srcfile] + +# a stop on the above line as reported by GDB +set loop_line "$loop\[^\\\r\\\n\]*/\\\* loop \\\*/" + +# make sure $line matches the full expected output per thread. +# and let's hope that GDB never mixes the output from different threads. +# +# this is quite fragile, mostly because the prompt appears somewhere in +# the middle of the output. +proc gdb_cont_to { threads cmd line nthreads } { + global gdb_prompt + set full_cmd "thread apply $threads $cmd" + set prompt_seen 0 + + send_gdb "$full_cmd\n" + + for {set i 0} {$i < $nthreads} {incr i} { + set test "$full_cmd: thread $i" + + # check for the prompt. it may be in front of one of the lines we + # try to match. + gdb_test_multiple "" "$test: check prompt" { + -notransfer -re "$gdb_prompt " { + set prompt_seen 1 + } + } + + # check for the line. and for a typical error. + gdb_test_multiple "" $test { + -re "Cannot execute this command \[^\\\r\\\n\]* is running\." { + fail $test + } + -re "$line\[^\\\r\\\n\]*\r\n" { + pass $test + } + } + } + + # make sure we consume the prompt if we have not skipped it before. + if {$prompt_seen == 0} { + set test "$full_cmd: consume prompt" + gdb_test_multiple "" $test { + -re "$gdb_prompt " { + pass $test + } + } + } +} + +proc gdb_cont_to_bp_line { line threads nthreads } { + gdb_cont_to $threads "continue" \ + [multi_line \ + "Breakpoint\[^\\\r\\\n\]*$line" \ + "\[^\\\r\\\n\]*" \ + ] \ + $nthreads +} + +proc gdb_cont_to_no_history { threads cmd nthreads } { + gdb_cont_to $threads $cmd \ + [multi_line \ + "No more reverse-execution history\." \ + "\[^\\\r\\\n\]*" \ + "\[^\\\r\\\n\]*" \ + ] \ + $nthreads +} + +# trace the code between the two breakpoints +gdb_cont_to_bp_line "$srcfile:$bp_1" all 2 +gdb_test_no_output "record btrace" +gdb_cont_to_bp_line "$srcfile:$bp_2" all 2 + +# we don't need those breakpoints any longer. +# they will only disturb our stepping. +delete_breakpoints + +# show the threads - this is useful for debugging fails +gdb_test "thread apply all info rec" ".*" +gdb_test "info threads" ".*" + +with_test_prefix "navigate" { + gdb_test "thread apply 1 record goto 2" "$loop_line" + gdb_test "thread apply 2 record goto 4" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 2\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 4\." + + gdb_test "thread apply all record goto 5" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 5\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 5\." +} + +with_test_prefix "step" { + with_test_prefix "thread 1" { + gdb_test "thread apply 1 stepi 2" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 7\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 5\." + } + + with_test_prefix "thread 2" { + gdb_test "thread apply 2 stepi 3" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 7\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 8\." + } + + with_test_prefix "all" { + gdb_cont_to all "stepi 4" "$loop_line" 2 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 11\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 12\." + } +} + +with_test_prefix "reverse-step" { + with_test_prefix "thread 1" { + gdb_test "thread apply 1 reverse-stepi 2" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 9\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 12\." + } + + with_test_prefix "thread 2" { + gdb_test "thread apply 2 reverse-stepi 3" "$loop_line" + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 9\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 9\." + } + + with_test_prefix "all" { + gdb_cont_to all "reverse-stepi 4" "$loop_line" 2 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 5\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 5\." + } +} + +with_test_prefix "continue" { + with_test_prefix "thread 1" { + gdb_cont_to_no_history 1 "continue" 1 + gdb_test "thread apply 1 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 5\." + + gdb_cont_to_no_history 1 "reverse-continue" 1 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 1\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 5\." + } + + with_test_prefix "thread 2" { + gdb_cont_to_no_history 2 "continue" 1 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 1\." + gdb_test "thread apply 2 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + + gdb_cont_to_no_history 2 "reverse-continue" 1 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 1\." + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 1\." + } +} + +# a thread may only resume if no thread is still replaying +with_test_prefix "no progress" { + with_test_prefix "thread 1" { + gdb_test "thread apply 1 record goto end" ".*" + gdb_test "thread apply 2 record goto begin" ".*" + + gdb_cont_to_no_history 1 "continue" 1 + gdb_cont_to_no_history 1 "step" 1 + gdb_test "thread apply 1 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + gdb_test "thread apply 2 info record" \ + ".*Replay in progress\. At instruction 1\." + } + + with_test_prefix "thread 2" { + gdb_test "thread apply 1 record goto begin" ".*" + gdb_test "thread apply 2 record goto end" ".*" + + gdb_cont_to_no_history 2 "continue" 1 + gdb_cont_to_no_history 2 "step" 1 + gdb_test "thread apply 1 info record" \ + ".*Replay in progress\. At instruction 1\." + gdb_test "thread apply 2 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + } + + with_test_prefix "all" { + gdb_test "thread apply all record goto begin" ".*" + + gdb_cont_to_no_history all "continue" 2 + gdb_test "thread apply 1 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + gdb_test "thread apply 2 info record" \ + ".*Recorded \[0-9\]+ instructions \[^\\\r\\\n\]*" + } +} + +# now that both threads stopped replaying we may resume recording +with_test_prefix "cont to end" { + gdb_breakpoint $bp_3 + gdb_cont_to_bp_line "$srcfile:$bp_3" all 1 +} -- 1.8.3.1