* dwarf2read.c (dwarf2_die_debug): New static global.
(dump_die_shallow): Renamed from dump_die, New args f, indent. Print to specified file, indented by the specified amount. (dump_die_for_error): New fn. Point all existing callers of dump_die here. (dump_die_die_1,dump_die): New fns, replaces ... (dump_die_list): ... deleted. (read_die_and_children_1): Old contents of read_die_and_children moved here. (read_die_and_children): Rewrite. (read_die_and_siblings): Call read_die_and_children_1 instead of read_die_and_children. (_initialize_dwarf2_read): New option "debug dwarf2-die". * gdbinit.in (pdie): New macro. * doc/gdb.texinfo (set debug dwarf2-die): Document it.
This commit is contained in:
parent
4545259105
commit
d97bc12be0
5 changed files with 169 additions and 33 deletions
|
@ -1,5 +1,20 @@
|
|||
2008-10-06 Doug Evans <dje@google.com>
|
||||
|
||||
* dwarf2read.c (dwarf2_die_debug): New static global.
|
||||
(dump_die_shallow): Renamed from dump_die, New args f, indent.
|
||||
Print to specified file, indented by the specified amount.
|
||||
(dump_die_for_error): New fn. Point all existing callers of
|
||||
dump_die here.
|
||||
(dump_die_die_1,dump_die): New fns, replaces ...
|
||||
(dump_die_list): ... deleted.
|
||||
(read_die_and_children_1): Old contents of read_die_and_children
|
||||
moved here.
|
||||
(read_die_and_children): Rewrite.
|
||||
(read_die_and_siblings): Call read_die_and_children_1 instead of
|
||||
read_die_and_children.
|
||||
(_initialize_dwarf2_read): New option "debug dwarf2-die".
|
||||
* gdbinit.in (pdie): New macro.
|
||||
|
||||
* dwarf2read.c (offset_in_cu_p): New function.
|
||||
(find_partial_die,follow_die_ref): Use it.
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2008-10-06 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.texinfo (set debug dwarf2-die): Document it.
|
||||
|
||||
2008-10-01 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.texinfo (catch) [exception]: Document how to insert
|
||||
|
|
|
@ -17019,6 +17019,13 @@ Display debugging messages about inner workings of the AIX thread
|
|||
module.
|
||||
@item show debug aix-thread
|
||||
Show the current state of AIX thread debugging info display.
|
||||
@item set debug dwarf2-die
|
||||
@cindex DWARF2 DIEs
|
||||
Dump DWARF2 DIEs after they are read in.
|
||||
The value is the number of nesting levels to print.
|
||||
A value of zero turns off the display.
|
||||
@item show debug dwarf2-die
|
||||
Show the current state of DWARF2 DIE debugging.
|
||||
@item set debug displaced
|
||||
@cindex displaced stepping debugging info
|
||||
Turns on or off display of @value{GDBN} debugging info for the
|
||||
|
|
159
gdb/dwarf2read.c
159
gdb/dwarf2read.c
|
@ -141,6 +141,9 @@ typedef struct statement_prologue
|
|||
}
|
||||
_STATEMENT_PROLOGUE;
|
||||
|
||||
/* When non-zero, dump DIEs after they are read in. */
|
||||
static int dwarf2_die_debug = 0;
|
||||
|
||||
/* When set, the file that we're processing is known to have debugging
|
||||
info for C++ namespaces. GCC 3.3.x did not produce this information,
|
||||
but later versions do. */
|
||||
|
@ -952,6 +955,11 @@ static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
|
|||
|
||||
static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *);
|
||||
|
||||
static struct die_info *read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd,
|
||||
struct dwarf2_cu *,
|
||||
gdb_byte **new_info_ptr,
|
||||
struct die_info *parent);
|
||||
|
||||
static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
|
||||
struct dwarf2_cu *,
|
||||
gdb_byte **new_info_ptr,
|
||||
|
@ -989,9 +997,14 @@ static char *dwarf_cfi_name (unsigned int);
|
|||
|
||||
static struct die_info *sibling_die (struct die_info *);
|
||||
|
||||
static void dump_die (struct die_info *);
|
||||
static void dump_die_shallow (struct ui_file *, int indent, struct die_info *);
|
||||
|
||||
static void dump_die_list (struct die_info *);
|
||||
static void dump_die_for_error (struct die_info *);
|
||||
|
||||
static void dump_die_1 (struct ui_file *, int level, int max_level,
|
||||
struct die_info *);
|
||||
|
||||
/*static*/ void dump_die (struct die_info *, int max_level);
|
||||
|
||||
static void store_in_ref_table (struct die_info *,
|
||||
struct dwarf2_cu *);
|
||||
|
@ -5207,6 +5220,27 @@ read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
|
|||
return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
|
||||
}
|
||||
|
||||
/* Main entry point for reading a DIE and all children.
|
||||
Read the DIE and dump it if requested. */
|
||||
|
||||
static struct die_info *
|
||||
read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
|
||||
struct dwarf2_cu *cu,
|
||||
gdb_byte **new_info_ptr,
|
||||
struct die_info *parent)
|
||||
{
|
||||
struct die_info *result = read_die_and_children_1 (info_ptr, abfd, cu,
|
||||
new_info_ptr, parent);
|
||||
|
||||
if (dwarf2_die_debug)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stdlog, "Read die from .debug_info:\n");
|
||||
dump_die (result, dwarf2_die_debug);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Read a single die and all its descendents. Set the die's sibling
|
||||
field to NULL; set other fields in the die correctly, and set all
|
||||
of the descendents' fields correctly. Set *NEW_INFO_PTR to the
|
||||
|
@ -5214,10 +5248,10 @@ read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
|
|||
is the parent of the die in question. */
|
||||
|
||||
static struct die_info *
|
||||
read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
|
||||
struct dwarf2_cu *cu,
|
||||
gdb_byte **new_info_ptr,
|
||||
struct die_info *parent)
|
||||
read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd,
|
||||
struct dwarf2_cu *cu,
|
||||
gdb_byte **new_info_ptr,
|
||||
struct die_info *parent)
|
||||
{
|
||||
struct die_info *die;
|
||||
gdb_byte *cur_ptr;
|
||||
|
@ -5266,7 +5300,7 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
|
|||
while (1)
|
||||
{
|
||||
struct die_info *die
|
||||
= read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent);
|
||||
= read_die_and_children_1 (cur_ptr, abfd, cu, &cur_ptr, parent);
|
||||
|
||||
if (die == NULL)
|
||||
{
|
||||
|
@ -7811,7 +7845,7 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
type = tag_type_to_type (type_die, cu);
|
||||
if (!type)
|
||||
{
|
||||
dump_die (type_die);
|
||||
dump_die_for_error (type_die);
|
||||
error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"),
|
||||
cu->objfile->name);
|
||||
}
|
||||
|
@ -7837,7 +7871,7 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
if (!type)
|
||||
{
|
||||
if (type_die)
|
||||
dump_die (type_die);
|
||||
dump_die_for_error (type_die);
|
||||
error (_("Dwarf Error: Problem turning containing type into gdb type [in module %s]"),
|
||||
cu->objfile->name);
|
||||
}
|
||||
|
@ -7852,7 +7886,7 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
this_type = read_type_die (die, cu);
|
||||
if (!this_type)
|
||||
{
|
||||
dump_die (die);
|
||||
dump_die_for_error (die);
|
||||
error (_("Dwarf Error: Cannot find type of die [in module %s]"),
|
||||
cu->objfile->name);
|
||||
}
|
||||
|
@ -9070,38 +9104,52 @@ dwarf_cfi_name (unsigned cfi_opc)
|
|||
#endif
|
||||
|
||||
static void
|
||||
dump_die (struct die_info *die)
|
||||
dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
|
||||
dwarf_tag_name (die->tag), die->abbrev, die->offset);
|
||||
fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
|
||||
|
||||
if (die->parent != NULL)
|
||||
{
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, " parent at offset: 0x%x\n",
|
||||
die->parent->offset);
|
||||
}
|
||||
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, " has children: %s\n",
|
||||
dwarf_bool_name (die->child != NULL));
|
||||
|
||||
fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, " attributes:\n");
|
||||
|
||||
for (i = 0; i < die->num_attrs; ++i)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ",
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, " %s (%s) ",
|
||||
dwarf_attr_name (die->attrs[i].name),
|
||||
dwarf_form_name (die->attrs[i].form));
|
||||
|
||||
switch (die->attrs[i].form)
|
||||
{
|
||||
case DW_FORM_ref_addr:
|
||||
case DW_FORM_addr:
|
||||
fprintf_unfiltered (gdb_stderr, "address: ");
|
||||
fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), gdb_stderr);
|
||||
fprintf_unfiltered (f, "address: ");
|
||||
fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), f);
|
||||
break;
|
||||
case DW_FORM_block2:
|
||||
case DW_FORM_block4:
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_block1:
|
||||
fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
|
||||
fprintf_unfiltered (f, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
|
||||
break;
|
||||
case DW_FORM_ref1:
|
||||
case DW_FORM_ref2:
|
||||
case DW_FORM_ref4:
|
||||
fprintf_unfiltered (gdb_stderr, "constant ref: %ld (adjusted)",
|
||||
fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)",
|
||||
(long) (DW_ADDR (&die->attrs[i])));
|
||||
break;
|
||||
case DW_FORM_data1:
|
||||
|
@ -9110,44 +9158,80 @@ dump_die (struct die_info *die)
|
|||
case DW_FORM_data8:
|
||||
case DW_FORM_udata:
|
||||
case DW_FORM_sdata:
|
||||
fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
|
||||
fprintf_unfiltered (f, "constant: %ld", DW_UNSND (&die->attrs[i]));
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
case DW_FORM_strp:
|
||||
fprintf_unfiltered (gdb_stderr, "string: \"%s\"",
|
||||
fprintf_unfiltered (f, "string: \"%s\"",
|
||||
DW_STRING (&die->attrs[i])
|
||||
? DW_STRING (&die->attrs[i]) : "");
|
||||
break;
|
||||
case DW_FORM_flag:
|
||||
if (DW_UNSND (&die->attrs[i]))
|
||||
fprintf_unfiltered (gdb_stderr, "flag: TRUE");
|
||||
fprintf_unfiltered (f, "flag: TRUE");
|
||||
else
|
||||
fprintf_unfiltered (gdb_stderr, "flag: FALSE");
|
||||
fprintf_unfiltered (f, "flag: FALSE");
|
||||
break;
|
||||
case DW_FORM_indirect:
|
||||
/* the reader will have reduced the indirect form to
|
||||
the "base form" so this form should not occur */
|
||||
fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect");
|
||||
fprintf_unfiltered (f, "unexpected attribute form: DW_FORM_indirect");
|
||||
break;
|
||||
default:
|
||||
fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.",
|
||||
fprintf_unfiltered (f, "unsupported attribute form: %d.",
|
||||
die->attrs[i].form);
|
||||
break;
|
||||
}
|
||||
fprintf_unfiltered (gdb_stderr, "\n");
|
||||
fprintf_unfiltered (f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_die_list (struct die_info *die)
|
||||
dump_die_for_error (struct die_info *die)
|
||||
{
|
||||
while (die)
|
||||
dump_die_shallow (gdb_stderr, 0, die);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die)
|
||||
{
|
||||
int indent = level * 4;
|
||||
|
||||
gdb_assert (die != NULL);
|
||||
|
||||
if (level >= max_level)
|
||||
return;
|
||||
|
||||
dump_die_shallow (f, indent, die);
|
||||
|
||||
if (die->child != NULL)
|
||||
{
|
||||
dump_die (die);
|
||||
if (die->child != NULL)
|
||||
dump_die_list (die->child);
|
||||
if (die->sibling != NULL)
|
||||
dump_die_list (die->sibling);
|
||||
print_spaces (indent, f);
|
||||
fprintf_unfiltered (f, " Children:");
|
||||
if (level + 1 < max_level)
|
||||
{
|
||||
fprintf_unfiltered (f, "\n");
|
||||
dump_die_1 (f, level + 1, max_level, die->child);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_unfiltered (f, " [not printed, max nesting level reached]\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (die->sibling != NULL && level > 0)
|
||||
{
|
||||
dump_die_1 (f, level, max_level, die->sibling);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called from the pdie macro in gdbinit.in.
|
||||
It's not static so gcc will keep a copy callable from gdb. */
|
||||
|
||||
void
|
||||
dump_die (struct die_info *die, int max_level)
|
||||
{
|
||||
dump_die_1 (gdb_stdlog, 0, max_level, die);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -10491,4 +10575,13 @@ caching, which can slow down startup."),
|
|||
show_dwarf2_max_cache_age,
|
||||
&set_dwarf2_cmdlist,
|
||||
&show_dwarf2_cmdlist);
|
||||
|
||||
add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
|
||||
Set debugging of the dwarf2 DIE reader."), _("\
|
||||
Show debugging of the dwarf2 DIE reader."), _("\
|
||||
When enabled (non-zero), DIEs are dumped after they are read in.\n\
|
||||
The value is the maximum depth to print."),
|
||||
NULL,
|
||||
NULL,
|
||||
&setdebuglist, &showdebuglist);
|
||||
}
|
||||
|
|
|
@ -15,3 +15,20 @@ dir @srcdir@/../bfd
|
|||
dir @srcdir@
|
||||
dir .
|
||||
set prompt (top-gdb)
|
||||
|
||||
define pdie
|
||||
if $argc == 1
|
||||
call dump_die ($arg0, 1)
|
||||
else
|
||||
if $argc == 2
|
||||
call dump_die ($arg0, $arg1)
|
||||
else
|
||||
printf "Syntax: pdie die [depth]\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
document pdie
|
||||
Pretty print a DWARF DIE.
|
||||
Syntax: pdie die [depth]
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue