diff options
-rw-r--r-- | gdb/record-btrace.c | 59 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/non-stop.c | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/non-stop.exp | 19 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/stop.exp | 70 |
4 files changed, 147 insertions, 7 deletions
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 1998e43..7da78bc 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -97,6 +97,11 @@ static struct cmd_list_element *show_record_btrace_pt_cmdlist; } \ while (0) +static void record_btrace_set_replay (struct thread_info *tp, + const struct btrace_insn_iterator *it); + +static void record_btrace_stop_replaying (struct thread_info *tp); + /* Update the branch trace for the current thread and return a pointer to its thread_info. @@ -252,9 +257,57 @@ record_btrace_stop_recording (struct target_ops *self) record_btrace_auto_disable (); - ALL_NON_EXITED_THREADS (tp) - if (tp->btrace.target != NULL) - btrace_disable (tp); + /* In non-stop mode, we indicate the implicit move of each replaying thread. + In stop-all mode, we indicate the implicit move of the selected thread if + it is replaying. Other threads are silently moved. The MI notification + will indicate that all threads have been stopped which should be enough to + indicate this implicit move to front-ends. */ + if (non_stop) + { + ALL_NON_EXITED_THREADS (tp) + if (tp->btrace.target != NULL) + { + if (btrace_is_replaying (tp)) + { + printf_filtered (_("Thread %s (%s) stopped replaying.\n"), + print_thread_id (tp), + target_pid_to_str (tp->ptid)); + record_btrace_set_replay (tp, NULL); + } + + btrace_disable (tp); + } + } + else + { + int send_stopped = 0; + + /* If the selected thread is replaying, we do an implicit "record goto + end" to make it stop replaying and indicate this to front-ends. This + causes the updated location to be printed for the selected thread. + + If it isn't replaying, we will send an unspecific stopped notification + to front-ends at the end. This doesn't print the (unchanged) location + but indicates to front-ends that other thread's locations may have + changed. */ + tp = inferior_thread (); + if (tp != NULL && btrace_is_replaying (tp)) + record_btrace_set_replay (tp, NULL); + else + send_stopped = 1; + + ALL_NON_EXITED_THREADS (tp) + if (tp->btrace.target != NULL) + { + /* Stop replaying before we disable tracing to clear TP's register + state in addition to the btrace state. */ + record_btrace_stop_replaying (tp); + btrace_disable (tp); + } + + if (send_stopped) + observer_notify_normal_stop (NULL, 0); + } } /* The to_close method of target record-btrace. */ diff --git a/gdb/testsuite/gdb.btrace/non-stop.c b/gdb/testsuite/gdb.btrace/non-stop.c index c5870df..b4a7191 100644 --- a/gdb/testsuite/gdb.btrace/non-stop.c +++ b/gdb/testsuite/gdb.btrace/non-stop.c @@ -27,7 +27,9 @@ test (void *arg) i = 0; /* bp.1 */ for (; i < 10; ++i) global += i; /* loop */ - return arg; /* bp.2 */ + global *= 2; /* bp.2 */ + + return arg; /* bp.3 */ } int @@ -41,5 +43,5 @@ main (void) pthread_join (th, NULL); - return 0; /* bp.3 */ + return 0; } diff --git a/gdb/testsuite/gdb.btrace/non-stop.exp b/gdb/testsuite/gdb.btrace/non-stop.exp index 0d5cbe2..8dad07c 100644 --- a/gdb/testsuite/gdb.btrace/non-stop.exp +++ b/gdb/testsuite/gdb.btrace/non-stop.exp @@ -239,7 +239,22 @@ with_test_prefix "no progress" { } # now that both threads stopped replaying we may resume recording -with_test_prefix "cont to end" { +with_test_prefix "resume recording" { gdb_breakpoint $bp_3 - gdb_cont_to_bp_line "$srcfile:$bp_3" all 1 + gdb_cont_to_bp_line "$srcfile:$bp_3" all 2 +} + +# when we stop recording we get notifications for replaying threads +with_test_prefix "stop" { + gdb_test "thread 1" ".*" + gdb_test "thread apply 2 record goto begin" ".*" + + gdb_test "record stop" [multi_line \ + "Thread 2 \[^\\\r\\\n\]* stopped replaying\." \ + "\[^\\\r\\\n\]*$srcfile:$bp_3" \ + "$bp_3\[^\\\r\\\n\]* bp\.3 \[^\\\r\\\n\]*" \ + "Process record is stopped and all execution logs are deleted\." \ + ] + + gdb_test "info record" "No record target is currently active\." } diff --git a/gdb/testsuite/gdb.btrace/stop.exp b/gdb/testsuite/gdb.btrace/stop.exp new file mode 100644 index 0000000..074bab8 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/stop.exp @@ -0,0 +1,70 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2016 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 <http://www.gnu.org/licenses/>. + +# check for btrace support +if { [skip_btrace_tests] } { return -1 } + +standard_testfile record_goto.c + +# start inferior +if [prepare_for_testing $testfile.exp $testfile $srcfile] { + return -1 +} + +# we use the list command to check the current source location +gdb_test "set listsize 1" + +if ![runto_main] { + return -1 +} + +# trace the call to the test function +gdb_test_no_output "record btrace" "move: enable" +gdb_test "next" ".*main\.3.*" "move: trace" + +# move to the beginning of the trace +gdb_test "record goto begin" ".*main\.2.*" "move: navigate" + +# when we stop recording, we move back to the end of the trace +gdb_test "record stop" "main\.3.*Process record is stopped.*" "move: stop" + +# check that we're really there +gdb_test "list" ".*main\.3.*" "move: at end of trace" + +if ![runto_main] { + return -1 +} + +# trace the call to the test function +gdb_test_no_output "record btrace" "already: enable" +gdb_test "next" ".*main\.3.*" "already: trace" + +# we're already at the end so we didn't have to move +gdb_test_multiple "record stop" "already: stop" { + -re "main.*$gdb_prompt $" { + fail "already: stop" + } + -re "Process record is stopped\[^\\\r\\\n\]*\r\n$gdb_prompt $" { + pass "already: stop" + } + -re "$gdb_prompt $" { + fail "already: stop" + } +} + +# check that we're really there +gdb_test "list" ".*main\.3.*" "already: at end of trace" |