From a00d335a2d7b66e1a1fc51c6e772bae3066835f2 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Fri, 9 May 2025 10:33:44 +0000 Subject: [PATCH] gdb, record: notify frame change on 'record stop' when selected thread moves As a side effect of the 'record stop' command, threads may move to the end of their execution history if they had been replaying. When using CLI or TUI, there is no indication of that move for the selected thread. Notify about the frame change for the selected thread. This makes CLI print the selected frame and TUI update their view. Add a note to the MI record-stopped event. Reviewed-By: Eli Zaretskii Approved-By: Tom Tromey --- gdb/doc/gdb.texinfo | 3 +++ gdb/record-btrace.c | 7 +++++-- gdb/record.c | 19 ++++++++++--------- gdb/target-delegates-gen.c | 22 +++++++++++++--------- gdb/target.h | 6 +++--- gdb/testsuite/gdb.btrace/step.exp | 2 +- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 821f3ed4b05..854f22b612e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -32566,6 +32566,9 @@ method in use supports multiple recording formats, @var{format} will be present and contain the currently used format. @xref{Process Record and Replay}, for existing method and format values. +If recording was stopped for the btrace method, threads move to the +end of their execution history. + @item =cmd-param-changed,param=@var{param},value=@var{value} Reports that a parameter of the command @code{set @var{param}} is changed to @var{value}. In the multi-word @code{set} command, diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 4087a26f5b5..80d22a9b4b6 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -80,7 +80,7 @@ public: enum record_method record_method (ptid_t ptid) override; - void stop_recording () override; + bool stop_recording () override; void info_record () override; void insn_history (int size, gdb_disassembly_flags flags) override; @@ -408,17 +408,20 @@ record_btrace_target_open (const char *args, int from_tty) /* The stop_recording method of target record-btrace. */ -void +bool record_btrace_target::stop_recording () { DEBUG ("stop recording"); + bool is_replaying = record_is_replaying (inferior_ptid); record_stop_replaying (); record_btrace_auto_disable (); for (thread_info &tp : current_inferior ()->non_exited_threads ()) if (tp.btrace.target != NULL) btrace_disable (&tp); + + return is_replaying; } /* The disconnect method of target record-btrace. */ diff --git a/gdb/record.c b/gdb/record.c index de1a7a87a8e..7f3cf541bf1 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -151,12 +151,12 @@ record_read_memory (struct gdbarch *gdbarch, /* Stop recording. */ -static void +static bool record_stop (struct target_ops *t) { DEBUG ("stop %s", t->shortname ()); - t->stop_recording (); + return t->stop_recording (); } /* Unpush the record target. */ @@ -178,7 +178,7 @@ record_disconnect (struct target_ops *t, const char *args, int from_tty) DEBUG ("disconnect %s", t->shortname ()); - record_stop (t); + (void) record_stop (t); record_unpush (t); target_disconnect (args, from_tty); @@ -193,7 +193,7 @@ record_detach (struct target_ops *t, inferior *inf, int from_tty) DEBUG ("detach %s", t->shortname ()); - record_stop (t); + (void) record_stop (t); record_unpush (t); target_detach (inf, from_tty); @@ -305,17 +305,18 @@ cmd_record_delete (const char *args, int from_tty) static void cmd_record_stop (const char *args, int from_tty) { - struct target_ops *t; - - t = require_record_target (); - - record_stop (t); + struct target_ops *t = require_record_target (); + bool thread_moved = record_stop (t); record_unpush (t); gdb_printf (_("Process record is stopped and all execution " "logs are deleted.\n")); interps_notify_record_changed (current_inferior (), 0, NULL, NULL); + + /* INFERIOR_PTID may have moved when we stopped recording. */ + if (thread_moved) + notify_user_selected_context_changed (USER_SELECTED_FRAME); } diff --git a/gdb/target-delegates-gen.c b/gdb/target-delegates-gen.c index 164ddbb9a2e..e10a9fa0b05 100644 --- a/gdb/target-delegates-gen.c +++ b/gdb/target-delegates-gen.c @@ -172,7 +172,7 @@ struct dummy_target : public target_ops enum btrace_error read_btrace (struct btrace_data *arg0, struct btrace_target_info *arg1, enum btrace_read_type arg2) override; const struct btrace_config *btrace_conf (const struct btrace_target_info *arg0) override; enum record_method record_method (ptid_t arg0) override; - void stop_recording () override; + bool stop_recording () override; void info_record () override; void save_record (const char *arg0) override; bool supports_delete_record () override; @@ -353,7 +353,7 @@ struct debug_target : public target_ops enum btrace_error read_btrace (struct btrace_data *arg0, struct btrace_target_info *arg1, enum btrace_read_type arg2) override; const struct btrace_config *btrace_conf (const struct btrace_target_info *arg0) override; enum record_method record_method (ptid_t arg0) override; - void stop_recording () override; + bool stop_recording () override; void info_record () override; void save_record (const char *arg0) override; bool supports_delete_record () override; @@ -3794,24 +3794,28 @@ debug_target::record_method (ptid_t arg0) return result; } -void +bool target_ops::stop_recording () { - this->beneath ()->stop_recording (); + return this->beneath ()->stop_recording (); } -void +bool dummy_target::stop_recording () { + return false; } -void +bool debug_target::stop_recording () { target_debug_printf_nofunc ("-> %s->stop_recording (...)", this->beneath ()->shortname ()); - this->beneath ()->stop_recording (); - target_debug_printf_nofunc ("<- %s->stop_recording ()", - this->beneath ()->shortname ()); + bool result + = this->beneath ()->stop_recording (); + target_debug_printf_nofunc ("<- %s->stop_recording () = %s", + this->beneath ()->shortname (), + target_debug_print_bool (result).c_str ()); + return result; } void diff --git a/gdb/target.h b/gdb/target.h index 40823253a0f..eb8ead4a33c 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1236,9 +1236,9 @@ struct target_ops virtual enum record_method record_method (ptid_t ptid) TARGET_DEFAULT_RETURN (RECORD_METHOD_NONE); - /* Stop trace recording. */ - virtual void stop_recording () - TARGET_DEFAULT_IGNORE (); + /* Stop trace recording. Return whether the selected thread moved. */ + virtual bool stop_recording () + TARGET_DEFAULT_RETURN (false); /* Print information about the recording. */ virtual void info_record () diff --git a/gdb/testsuite/gdb.btrace/step.exp b/gdb/testsuite/gdb.btrace/step.exp index aba43ae4f3d..55b8b5d0b69 100644 --- a/gdb/testsuite/gdb.btrace/step.exp +++ b/gdb/testsuite/gdb.btrace/step.exp @@ -50,7 +50,7 @@ with_test_prefix "replay" { # Stop recording and try to step live (pr19340). with_test_prefix "live" { - gdb_test "record stop" "Process record is stopped.*" + gdb_test "record stop" "Process record is stopped.*fun4\.4.*" gdb_test "reverse-next" "Reverse execution is not currently supported.*" gdb_test "step" ".*fun3\.2.*" } -- 2.47.3