[PATCH] gdb: invalidate register cache after monitor commands

Jerry Zhang Jian <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
A monitor command is opaque to GDB: the stub can halt, resume, or
reset the target behind GDB's back, even if it later reports an
error, and the remote protocol has no way to tell GDB that happened.
For example, "monitor reset halt" was leaving GDB reporting the
pre-reset $pc until a later step/continue forced a refetch.

Invalidate the register cache after every monitor command via
SCOPE_EXIT, so it still runs on the error path.  Scope it to the
inferior's own process_stratum_target, matching registers_changed_thread()
and the target_wait()/target_stop() lookup pattern elsewhere in this
file, rather than wiping every inferior's cache with registers_changed().
Hold a strong reference to the target across the call in case it gets
unpushed/detached, the same idiom used in target_detach().

Signed-off-by: Jerry Zhang Jian <[email protected]>
---
 gdb/target.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gdb/target.c b/gdb/target.c
index 5d937f3ae85..5c4684d81b5 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -4262,6 +4262,18 @@ default_rcmd (struct target_ops *self, const char *command,
 static void
 do_monitor_command (const char *cmd, int from_tty)
 {
+  process_target_ops_ref proc_target_ref;
+  if (process_stratum_target *proc_target
+	= current_inferior ()->process_target ())
+    proc_target_ref = process_target_ops_ref::new_reference (proc_target);
+
+  /* Monitor commands may change target state behind GDB's back.  */
+  SCOPE_EXIT
+    {
+      if (proc_target_ref != nullptr)
+	registers_changed_ptid (proc_target_ref.get (), minus_one_ptid);
+    };
+
   target_rcmd (cmd, gdb_stdtarg);
 }
 
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.