This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/3] Reimplement support for "maint print registers" with no running inferior yet


A following patch will change the default target_thread_architecture
method, like this:

   struct gdbarch *
   default_thread_architecture (struct target_ops *ops, ptid_t ptid)
   {
  -  return target_gdbarch ();
  +  inferior *inf = find_inferior_ptid (ptid);
  +  gdb_assert (inf != NULL);
  +  return inf->gdbarch;
   }

This is because target_gdbarch is really just
current_inferior()->gdbarch, and it's wrong to return that
architecture when the inferior of the passed in PTID is NOT the
current inferior -- the inferior for PTID may be running a different
architecture.  E.g., a mix of 64-bit and 32-bit inferiors in the same
debug session.

Doing that change above however exposes a problem in "maint print
registers", caught be the testsuite:

 -PASS: gdb.base/maint.exp: maint print registers
 +FAIL: gdb.base/maint.exp: maint print registers (GDB internal error)
...
  gdb/inferior.c:309: internal-error: inferior* find_inferior_pid(int): Assertion `pid != 0' failed.
  A problem internal to GDB has been detected,

The call stack looks like this:

  #0  0x000000000068b707 in internal_error(char const*, int, char const*, ...) (file=0xa9b958 "gdb/inferior.c", line=309, fmt=0xa9b8e0 "%s: Assertion `%s' failed.") at gdb/common/errors.c:54
  #1  0x00000000006e1c40 in find_inferior_pid(int) (pid=0) at gdb/inferior.c:309
  #2  0x00000000006e1c8d in find_inferior_ptid(ptid_t) (ptid=...) at gdb/inferior.c:323
  #3  0x00000000007c18dc in default_thread_architecture(target_ops*, ptid_t) (ops=0xf86d60 <dummy_target>, ptid=...)
      at gdb/target.c:3134
  #4  0x00000000007b5414 in delegate_thread_architecture(target_ops*, ptid_t) (self=0xf86d60 <dummy_target>, arg1=...)
      at gdb/target-delegates.c:2527
  #5  0x00000000007647b3 in get_thread_regcache(ptid_t) (ptid=...) at gdb/regcache.c:466
  #6  0x00000000007647ff in get_current_regcache() () at gdb/regcache.c:475
  #7  0x0000000000767495 in regcache_print(char const*, regcache_dump_what) (args=0x0, what_to_dump=regcache_dump_none)
      at gdb/regcache.c:1599
  #8  0x0000000000767550 in maintenance_print_registers(char const*, int) (args=0x0, from_tty=1)
      at gdb/regcache.c:1613

I.e., the test does "maint print registers" while the inferior is not
running yet.  This is expected to work, and there's already a hack in
get_thread_arch_regcache to make it work.

Instead of pilling on hacks in the internal of regcache and
target_ops, this commit moves the null_ptid special casing to where it
belongs -- higher up in the call chain in the implementation of "maint
print registers" & co directly.

gdb/ChangeLog:
2017-10-02  Pedro Alves  <palves@redhat.com>

	* regcache.c (get_thread_arch_regcache): Remove null_ptid special
	case.
	(regcache_print): Handle !target_has_registers here instead.
---
 gdb/regcache.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/gdb/regcache.c b/gdb/regcache.c
index acec972..bf448ef 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -439,17 +439,7 @@ get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
 struct regcache *
 get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
 {
-  struct address_space *aspace;
-
-  /* For the benefit of "maint print registers" & co when debugging an
-     executable, allow dumping the regcache even when there is no
-     thread selected (target_thread_address_space internal-errors if
-     no address space is found).  Note that normal user commands will
-     fail higher up on the call stack due to no
-     target_has_registers.  */
-  aspace = (ptid_equal (null_ptid, ptid)
-	    ? NULL
-	    : target_thread_address_space (ptid));
+  address_space *aspace = target_thread_address_space (ptid);
 
   return get_thread_arch_aspace_regcache  (ptid, gdbarch, aspace);
 }
@@ -1595,15 +1585,28 @@ regcache::dump (ui_file *file, enum regcache_dump_what what_to_dump)
 static void
 regcache_print (const char *args, enum regcache_dump_what what_to_dump)
 {
+  /* Where to send output.  */
+  stdio_file file;
+  ui_file *out;
+
   if (args == NULL)
-    get_current_regcache ()->dump (gdb_stdout, what_to_dump);
+    out = gdb_stdout;
   else
     {
-      stdio_file file;
-
       if (!file.open (args, "w"))
 	perror_with_name (_("maintenance print architecture"));
-      get_current_regcache ()->dump (&file, what_to_dump);
+      out = &file;
+    }
+
+  if (target_has_registers)
+    get_current_regcache ()->dump (out, what_to_dump);
+  else
+    {
+      /* For the benefit of "maint print registers" & co when
+	 debugging an executable, allow dumping a regcache even when
+	 there is no thread selected / no registers.  */
+      regcache dummy_regs (target_gdbarch (), nullptr);
+      dummy_regs.dump (out, what_to_dump);
     }
 }
 
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]