forked from Imagelibrary/binutils-gdb
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-04 Pedro Alves <palves@redhat.com>
* regcache.c (get_thread_arch_regcache): Remove null_ptid special
case.
(regcache_print): Handle !target_has_registers here instead.
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
2017-10-04 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* regcache.c (get_thread_arch_regcache): Remove null_ptid special
|
||||||
|
case.
|
||||||
|
(regcache_print): Handle !target_has_registers here instead.
|
||||||
|
|
||||||
2017-10-04 Pedro Alves <palves@redhat.com>
|
2017-10-04 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* frame.c (create_test_frame): Delete.
|
* frame.c (create_test_frame): Delete.
|
||||||
|
|||||||
@@ -439,17 +439,7 @@ get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
|
|||||||
struct regcache *
|
struct regcache *
|
||||||
get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
|
get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct address_space *aspace;
|
address_space *aspace = target_thread_address_space (ptid);
|
||||||
|
|
||||||
/* 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));
|
|
||||||
|
|
||||||
return get_thread_arch_aspace_regcache (ptid, gdbarch, aspace);
|
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
|
static void
|
||||||
regcache_print (const char *args, enum regcache_dump_what what_to_dump)
|
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)
|
if (args == NULL)
|
||||||
get_current_regcache ()->dump (gdb_stdout, what_to_dump);
|
out = gdb_stdout;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stdio_file file;
|
|
||||||
|
|
||||||
if (!file.open (args, "w"))
|
if (!file.open (args, "w"))
|
||||||
perror_with_name (_("maintenance print architecture"));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user