aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/record-btrace.c59
-rw-r--r--gdb/testsuite/gdb.btrace/non-stop.c6
-rw-r--r--gdb/testsuite/gdb.btrace/non-stop.exp19
-rw-r--r--gdb/testsuite/gdb.btrace/stop.exp70
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"