diff options
Diffstat (limited to 'gdb/record-btrace.c')
-rw-r--r-- | gdb/record-btrace.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 1998e43fcd0..7da78bc508c 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. */ |