From: Markus Metzger Date: Fri, 9 May 2025 10:33:44 +0000 (+0000) Subject: gdb, record: notify_normal_stop on 'record stop' when selected thread moves X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18c82d81fe9cbc05a4a85d8ee77904313bd1f17b;p=thirdparty%2Fbinutils-gdb.git gdb, record: notify_normal_stop on 'record stop' when selected thread moves As a side effect of the 'record stop' command, the selected thread may move to the end of the execution history if it had been replaying. Call notify_normal_stop () in this case to tell users about the change in location. --- diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 98bb17dea53..a04c0dae1cd 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 440c5e95e42..0adfbde0bc7 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -152,12 +152,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. */ @@ -179,7 +179,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); @@ -194,7 +194,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); @@ -306,16 +306,17 @@ 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 notify_stop = record_stop (t); record_unpush (t); gdb_printf (_("Process record is stopped and all execution " "logs are deleted.\n")); + /* INFERIOR_PTID may have moved when we stopped recording. */ + if (notify_stop) + notify_normal_stop (nullptr, true); + interps_notify_record_changed (current_inferior (), 0, NULL, NULL); } 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 2d3bac77bd2..bb3ce856bdd 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 2c46c76f872..486fa3dbc22 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" "Target .* does not support this command.*" gdb_test "step" ".*fun3\.2.*" }