* [RFA] Delayed physname computation
@ 2010-04-20 20:23 Keith Seitz
2010-04-21 6:38 ` Jan Kratochvil
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Keith Seitz @ 2010-04-20 20:23 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1857 bytes --]
Hi,
This is actually a patch for symtab/11465.
Basically, dwarf2_physname is constructing the name of a class method in
which one of the method's parameters is of a type that has not yet been
fully processed. (c_type_print_args will say "<incomplete type>"). Bad
things happen in/under c_type_print_args when you give it an incomplete
type like this.
The solution I've implemented is to simply delay processing of method
physnames until the entire CU has been read/processed.
Unfortunately, this is another example in which the compiler used may
alter the test outcome. As a result, I've had to hack in a test case
which is independent of the compiler. I would appreciate special
attention to the test source file (pr11465.S), which is an edited
version of gcc's --save-temps output.
I have regression tested this on x86 and x86_64 linux. There aer no
regressions, and the new test now passes.
Keith
ChangeLog
2010-04-20 Keith Seitz <keiths@redhat.com>
* dwarf2read.c (struct delayed_method_info): New struct.
(struct dwarf2_cu): Add members method_index and method_list.
(struct dwarf2_per_cu_data): Add member num_methods.
(count_partial_methods): New function.
(scan_partial_symbols): Count methods for union, class, structure,
and interface types.
(add_partial_subprogram): Count methods here, too.
(add_to_method_list): New function.
(compute_delayed_physnames): New function.
(process_full_comp_unit): Allocate the CU's methods list,
compute delayed physnames, and free the method list.
(dwarf2_add_member_fn): For C++ and Java, delay the computation
of the physname until after the CU is read.
(load_partial_dies): Add subprogram and lexical block DIEs
for Java and C++, too.
testsuite/ChangeLog
2010-04-20 Keith Seitz <keiths@redhat.com>
* gdb.dwarf2/pr11465.exp: New test.
* gdb.dwarf2/pr11465.S: New file.
[-- Attachment #2: delayed_physnames.patch --]
[-- Type: text/plain, Size: 24361 bytes --]
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.379
diff -u -p -r1.379 dwarf2read.c
--- dwarf2read.c 20 Apr 2010 17:33:14 -0000 1.379
+++ dwarf2read.c 20 Apr 2010 19:51:56 -0000
@@ -215,6 +215,26 @@ struct comp_unit_head
unsigned int first_die_offset;
};
+/* Type used for delaying computation of method physnames.
+ See comments for compute_delayed_physnames. */
+struct delayed_method_info
+{
+ /* The type to which the method is attached, i.e., its parent class. */
+ struct type *type;
+
+ /* The index of the method in the type's function fieldlists. */
+ int fnfield_index;
+
+ /* The index of the method in the fieldlist. */
+ int index;
+
+ /* The name of the DIE. */
+ const char *name;
+
+ /* The DIE associated with this method. */
+ struct die_info *die;
+};
+
/* Internal state when decoding a particular compilation unit. */
struct dwarf2_cu
{
@@ -293,6 +313,11 @@ struct dwarf2_cu
/* Header data from the line table, during full symbol processing. */
struct line_header *line_header;
+ /* A list of methods which need to have physnames computed
+ after all type information has been read. */
+ int method_index;
+ struct delayed_method_info *method_list;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
@@ -350,6 +375,10 @@ struct dwarf2_per_cu_data
or NULL for partial units (which do not have an associated
symtab). */
struct partial_symtab *psymtab;
+
+ /* The total number of methods found in the CU. This field is
+ used to allocate memory for delayed physname processing. */
+ int num_methods;
};
/* Entry in the signatured_types hash table. */
@@ -1124,6 +1153,9 @@ static void dwarf2_clear_marks (struct d
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
+static const char *dwarf2_physname (char *name, struct die_info *die,
+ struct dwarf2_cu *cu);
+
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something. */
@@ -2179,6 +2211,24 @@ create_all_comp_units (struct objfile *o
dwarf2_per_objfile->n_comp_units = n_comp_units;
}
+/* Count the number of methods in partial die PDI and its children, if any.
+ The result is recorded in CU. This is used to give an upper bound
+ for the number of slots needed in the delayed method list in the CU.
+ See compute_delayed_physnames. */
+static void
+count_partial_methods (struct partial_die_info *pdi, struct dwarf2_cu *cu)
+{
+ struct partial_die_info *die;
+ for (die = pdi->die_child; die; die = die->die_sibling)
+ {
+ if (die->tag == DW_TAG_subprogram)
+ ++(cu->per_cu->num_methods);
+
+ if (die->has_children)
+ count_partial_methods (die, cu);
+ }
+}
+
/* Process all loaded DIEs for compilation unit CU, starting at
FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
@@ -2216,9 +2266,11 @@ scan_partial_symbols (struct partial_die
case DW_TAG_subprogram:
add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
break;
+ case DW_TAG_union_type:
+ count_partial_methods (pdi, cu);
+ /* fall through */
case DW_TAG_variable:
case DW_TAG_typedef:
- case DW_TAG_union_type:
if (!pdi->is_declaration)
{
add_partial_symbol (pdi, cu);
@@ -2227,10 +2279,9 @@ scan_partial_symbols (struct partial_die
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
+ count_partial_methods (pdi, cu);
if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
+ add_partial_symbol (pdi, cu);
break;
case DW_TAG_enumeration_type:
if (!pdi->is_declaration)
@@ -2578,6 +2629,7 @@ add_partial_subprogram (struct partial_d
{
if (pdi->tag == DW_TAG_subprogram)
{
+ count_partial_methods (pdi, cu);
if (pdi->has_pc_info)
{
if (pdi->lowpc < *lowpc)
@@ -3107,6 +3159,41 @@ load_full_comp_unit (struct dwarf2_per_c
discard_cleanups (free_cu_cleanup);
}
+static void
+add_to_method_list (struct type *type, int fnfield_index, int index,
+ const char *name, struct die_info *die,
+ struct dwarf2_cu *cu)
+{
+ struct delayed_method_info *mi;
+ gdb_assert (cu->method_index < cu->per_cu->num_methods);
+ mi = &cu->method_list[cu->method_index++];
+ mi->type = type;
+ mi->fnfield_index = fnfield_index;
+ mi->index = index;
+ mi->name = name;
+ mi->die = die;
+}
+
+/* Compute the physnames of any methods on the CU's method list.
+
+ The computation of method physnames is delayed in order to avoid the
+ (bad) condition that one of the method's formal parameters is of an as yet
+ incomplete type. */
+static void
+compute_delayed_physnames (struct dwarf2_cu *cu)
+{
+ int i;
+ for (i = 0; i < cu->method_index; ++i)
+ {
+ char *physname;
+ struct delayed_method_info *mi = &cu->method_list[i];
+ struct fn_fieldlist *fn_flp
+ = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
+ physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+ fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+ }
+}
+
/* Generate full symbol information for PST and CU, whose DIEs have
already been loaded into memory. */
@@ -3129,11 +3216,29 @@ process_full_comp_unit (struct dwarf2_pe
cu->list_in_scope = &file_symbols;
+ /* If methods were found in the partial symbol table, we allocate one
+ big buffer to hold the entire delayed list for the CU. */
+ if (per_cu->num_methods)
+ {
+ cu->method_list
+ = xmalloc (per_cu->num_methods * sizeof (struct delayed_method_info));
+ }
+
dwarf2_find_base_address (cu->dies, cu);
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
+ /* Now that we have processed all the DIEs in the CU, all the types
+ should be complete, and it should now be safe to compute all of the
+ physnames. */
+ if (per_cu->num_methods)
+ {
+ compute_delayed_physnames (cu);
+ xfree (cu->method_list);
+ cu->method_list = NULL;
+ }
+
/* Some compilers don't define a DW_AT_high_pc attribute for the
compilation unit. If the DW_AT_high_pc is missing, synthesize
it, by scanning the DIE's below the compilation unit. */
@@ -4756,7 +4861,6 @@ dwarf2_add_member_fn (struct field_info
int i;
struct fn_field *fnp;
char *fieldname;
- char *physname;
struct nextfnfield *new_fnfield;
struct type *this_type;
@@ -4768,9 +4872,6 @@ dwarf2_add_member_fn (struct field_info
if (fieldname == NULL)
return;
- /* Get the mangled name. */
- physname = (char *) dwarf2_physname (fieldname, die, cu);
-
/* Look up member function name in fieldlist. */
for (i = 0; i < fip->nfnfields; i++)
{
@@ -4796,7 +4897,7 @@ dwarf2_add_member_fn (struct field_info
flp->name = fieldname;
flp->length = 0;
flp->head = NULL;
- fip->nfnfields++;
+ i = fip->nfnfields++;
}
/* Create a new member function field and chain it to the field list
@@ -4810,9 +4911,19 @@ dwarf2_add_member_fn (struct field_info
/* Fill in the member function field info. */
fnp = &new_fnfield->fnfield;
- /* The name is already allocated along with this objfile, so we don't
- need to duplicate it for the type. */
- fnp->physname = physname ? physname : "";
+
+ /* Delay processing of the physname until later. */
+ if (cu->language == language_cplus || cu->language == language_java)
+ {
+ add_to_method_list (type, i, flp->length - 1, fieldname,
+ die, cu);
+ }
+ else
+ {
+ char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+ fnp->physname = physname ? physname : "";
+ }
+
fnp->type = alloc_type (objfile);
this_type = read_type_die (die, cu);
if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
@@ -4838,7 +4949,7 @@ dwarf2_add_member_fn (struct field_info
}
else
complaint (&symfile_complaints, _("member function type missing for '%s'"),
- physname);
+ dwarf2_physname (fieldname, die, cu));
/* Get fcontext from DW_AT_containing_type if present. */
if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
@@ -6779,7 +6890,9 @@ load_partial_dies (bfd *abfd, gdb_byte *
|| last_die->tag == DW_TAG_interface_type
|| last_die->tag == DW_TAG_structure_type
|| last_die->tag == DW_TAG_union_type))
- || (cu->language == language_ada
+ || ((cu->language == language_ada
+ || cu->language == language_cplus
+ || cu->language == language_java)
&& (last_die->tag == DW_TAG_subprogram
|| last_die->tag == DW_TAG_lexical_block))))
{
Index: testsuite/gdb.dwarf2/pr11465.exp
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.exp
diff -N testsuite/gdb.dwarf2/pr11465.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.exp 20 Apr 2010 20:03:45 -0000
@@ -0,0 +1,40 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+ && ![istarget *-*-gnu*]
+ && ![istarget *-*-elf*]
+ && ![istarget *-*-openbsd*]
+ && ![istarget arm-*-eabi*]
+ && ![istarget powerpc-*-eabi*]} {
+ return 0
+}
+
+set testfile "pr11465"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+set binfile ${objdir}/${subdir}/${executable}
+
+# First try referencing DW_AT_frame_base which is not defined.
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+ return -1
+}
+
+clean_restart $executable
+
+# Test delayed physname computations
+gdb_test "p N::c.C" "\\$\[0-9]+ = \\{void \\(N::C \\*, void \\(\\*\\)\\(N::C\\)\\)\\}.*"
Index: testsuite/gdb.dwarf2/pr11465.S
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.S
diff -N testsuite/gdb.dwarf2/pr11465.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.S 20 Apr 2010 20:03:51 -0000
@@ -0,0 +1,415 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Compiled from:
+
+ namespace N
+ {
+ class C
+ {
+ public:
+ typedef void (*t) (C);
+ C (t) {}
+ };
+ typedef C::t u;
+ u f;
+ C c (f);
+ };
+
+ int
+ main ()
+ {
+ return 0;
+ }
+*/
+
+ .section .text
+_ZN1N1cE:
+ .section .debug_info
+d:
+ .long .Ldebug_info_end - 1f /* Length of CU info */
+1:
+ .value 0x2 /* DWARF version number */
+ .Long .Ldebug_abbrev0 /* Abbrev offset */
+ .byte 0x4 /* Pointer size */
+dieb: .uleb128 0x1 /* DW_TAG_compile_unit */
+ .long .LASF4 /* DW_AT_producer */
+ .byte 0x4 /* DW_AT_language */
+ .long .LASF5 /* DW_AT_name */
+ .long .LASF6 /* DW_AT_comp_dir */
+ .long 0x0 /* DW_AT_low_pc */
+ .long 0x0 /* DW_AT_entry_pc */
+ .long 0x0 /* DW_AT_ranges */
+ .long 0x0 /* DW_AT_stmt_list */
+die29: .uleb128 0x2 /* DW_TAG_namespace */
+ .string "N" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x1 /* DW_AT_decl_line */
+ .long die5e /* DW_AT_sibling */
+die32: .uleb128 0x3 /* DW_TAG_class_type */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_declaration */
+die36: .uleb128 0x4 /* DW_TAG_typedef */
+ .string "u" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x7 /* DW_AT_decl_line */
+ .long die7e /* DW_AT_type */
+die3f: .uleb128 0x5 /* DW_TAG_variable */
+ .string "f" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x8 /* DW_AT_decl_line */
+ .long .LASF0 /* DW_AT_MIPS_linkage_name */
+ .long die36 /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+die4e: .uleb128 0x5 /* DW_TAG_variable */
+ .string "c" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x9 /* DW_AT_decl_line */
+ .long .LASF1 /* DW_AT_MIPS_linkage_name */
+ .long die5e /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+ .byte 0x0
+die5e: .uleb128 0x6 /* DW_TAG_class_type */
+ .long die32 /* DW_AT_specification */
+ .byte 0x1 /* DW_AT_byte_size */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x2 /* DW_AT_decl_line */
+ .long die7e /* DW_AT_sibling */
+die6a: .uleb128 0x7 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0x5 /* DW_AT_decl_line */
+ .byte 0x1 /* DW_AT_declaration */
+die71: .uleb128 0x8 /* DW_TAG_formal_parameter */
+ .long die8f /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+die77: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e /* DW_AT_type */
+ .byte 0x0
+ .byte 0x0
+die7e: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die84 /* DW_AT_type */
+die84: .uleb128 0xb /* DW_TAG_subroutine_type */
+ .long die8f /* DW_AT_sibling */
+die89: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die5e /* DW_AT_type */
+ .byte 0x0
+die8f: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die5e /* DW_AT_type */
+die95: .uleb128 0xc /* DW_TAG_subprogram */
+ .long die6a /* DW_AT_specification */
+ .byte 0x2 /* DW_AT_inline */
+ .long dieaf /* DW_AT_sibling */
+die9f: .uleb128 0xd /* DW_TAG_formal_parameter */
+ .long .LASF7 /* DW_AT_name */
+ .long dieaf /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+diea9: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e /* DW_AT_type */
+ .byte 0x0
+dieaf: .uleb128 0xe /* DW_TAG_const_type */
+ .long die8f /* DW_AT_type */
+dieb4: .uleb128 0xf /* DW_TAG_subprogram */
+ .long 0x95 /* DW_AT_abstract_origin */
+ .long .LFB2 /* DW_AT_low_pc */
+ .long .LFE2 /* DW_AT_high_pc */
+ .long .LLST0 /* DW_AT_frame_base */
+ .long dieda /* DW_AT_sibling */
+diec9: .uleb128 0x10 /* DW_TAG_subprogram */
+ .long 0x9f /* DW_AT_abstract_origin */
+ .byte 0x2 /* DW_AT_location */
+ .byte 0x91
+ .sleb128 0
+died1: .uleb128 0x10 /* DW_TAG_formal_parameter */
+ .long 0xa9 /* DW_AT_abstract_origin */
+ .byte 0x2 /* DW_AT_location */
+ .byte 0x91
+ .sleb128 4
+ .byte 0x0
+dieda: .uleb128 0x11 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .long .LASF8 /* DW_AT_name */
+ .byte 0x1 /* DW_AT_decl_file */
+ .byte 0xc /* DW_AT_decl_line */
+ .long dief2 /* DW_AT_type */
+ .long .LFB3 /* DW_AT_low_pc */
+ .long .LFE3 /* DW_AT_high_pc */
+ .long .LLST1 /* DW_AT_frame_base */
+dief2: .uleb128 0x12 /* DW_TAG_base_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .byte 0x5 /* DW_AT_encoding */
+ .string "int" /* DW_AT_name */
+die149: .uleb128 0x16 /* DW_TAG_variable */
+ .long die4e /* DW_AT_specification */
+ .byte 0x5 /* DW_AT_location */
+ .byte 0x3
+ .long _ZN1N1cE
+ .byte 0x0
+.Ldebug_info_end:
+ .section .debug_abbrev
+.Ldebug_abbrev0:
+ .uleb128 0x1 /* abbrev code*/
+ .uleb128 0x11 /* DW_TAG_compile_unit */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x25 /* DW_AT_producer*/
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x13 /* DW_AT_language */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x1b /* DW_AT_comp_dir */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x52 /* DW_AT_entry_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x55 /* DW_AT_ranges */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x10 /* DW_AT_stmt_list */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x2 /* abbrev code */
+ .uleb128 0x39 /* DW_TAG_namespace */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x1 /* DW_AT_sibling */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x3 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x4 /* abbrev code */
+ .uleb128 0x16 /* DW_TAG_typedef */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x5 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x2007 /* DW_AT_MIPS_linkage_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_TYPE */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x6 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x1 /* DW_AT_sibling */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x7 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogra */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x8 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x9 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xa /* abbrev code */
+ .uleb128 0xf /* DW_TAG_pointer_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xb /* abbrev code */
+ .uleb128 0x15 /* DW_TAG_subroutine_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x1 /* DW_AT_sibling */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xc /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x20 /* DW_AT_inline */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x1 /* DW_AT_sibling */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xd /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xe /* abbrev code */
+ .uleb128 0x26 /* DW_TAG_const_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xf /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x40 /* DW_AT_frame_base */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x1 /* DW_AT_sibling */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x10 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x11 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x40 /* DW_AT_frame_base */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x12 /* abbrev code */
+ .uleb128 0x24 /* DW_TAG_base_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3e /* DW_AT_encoding */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x16 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .byte 0x0
+ .section .debug_str
+.LASF0:
+ .string "_ZN1N1fE"
+.LASF7:
+ .string "this"
+.LASF6:
+ .string ""
+.LASF8:
+ .string "main"
+.LASF1:
+ .string "_ZN1N1cE"
+.LASF5:
+ .string "pr11465.cc"
+.LASF4:
+ .string "GNU C++ 4.4.2"
+ .ident "GCC: (GNU) 4.4.2"
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-20 20:23 [RFA] Delayed physname computation Keith Seitz
@ 2010-04-21 6:38 ` Jan Kratochvil
2010-04-23 23:04 ` Tom Tromey
2010-04-23 23:03 ` Tom Tromey
2010-04-25 10:33 ` Jan Kratochvil
2 siblings, 1 reply; 9+ messages in thread
From: Jan Kratochvil @ 2010-04-21 6:38 UTC (permalink / raw)
To: Keith Seitz; +Cc: gdb-patches
Hi Keith,
just fixed up / simplified the testcase.
m68k: gdb.dwarf2/pr11465.S:44: Error: unknown pseudo-op: `.value'
And with -nostdlib link to executable:
/usr/bin/ld: Dwarf Error: Can't find .debug_ranges section.
/usr/bin/ld: Dwarf Error: mangled line number section (bad file number).
/usr/bin/ld: Dwarf Error: mangled line number section (bad file number).
/usr/bin/ld: Dwarf Error: mangled line number section (bad file number).
/usr/bin/ld: Dwarf Error: mangled line number section (bad file number).
(.debug_info+0xb9): undefined reference to `.LFB2'
(.debug_info+0xbd): undefined reference to `.LFE2'
(.debug_info+0xc1): undefined reference to `.LLST0'
(.debug_info+0xe6): undefined reference to `.LFB3'
(.debug_info+0xea): undefined reference to `.LFE3'
(.debug_info+0xee): undefined reference to `.LLST1'
Thanks,
Jan
testsuite/
2010-04-21 Keith Seitz <keiths@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.dwarf2/pr11465.exp: New test.
* gdb.dwarf2/pr11465.S: New file.
--- /dev/null 2010-04-21 05:45:28.789093911 +0200
+++ gdb/testsuite/gdb.dwarf2/pr11465.exp 2010-04-21 08:29:26.000000000 +0200
@@ -0,0 +1,39 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+ && ![istarget *-*-gnu*]
+ && ![istarget *-*-elf*]
+ && ![istarget *-*-openbsd*]
+ && ![istarget arm-*-eabi*]
+ && ![istarget powerpc-*-eabi*]} {
+ return 0
+}
+
+set testfile "pr11465"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+set binfile ${objdir}/${subdir}/${executable}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+ return -1
+}
+
+clean_restart $executable
+
+# Test delayed physname computations
+gdb_test "p N::c.C" { = {void \(N::C \*, void \(\*\)\(N::C\)\)}.*}
--- /dev/null 2010-04-21 05:45:28.789093911 +0200
+++ gdb/testsuite/gdb.dwarf2/pr11465.S 2010-04-21 08:25:54.000000000 +0200
@@ -0,0 +1,355 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Compiled from:
+
+ namespace N
+ {
+ class C
+ {
+ public:
+ typedef void (*t) (C);
+ C (t) {}
+ };
+ typedef C::t u;
+ u f;
+ C c (f);
+ };
+
+ int
+ main ()
+ {
+ return 0;
+ }
+*/
+
+ .text
+_ZN1N1cE:
+ .section .debug_info
+d:
+ .long .Ldebug_info_end - 1f /* Length of CU info */
+1:
+ .2byte 0x2 /* DWARF version number */
+ .long .Ldebug_abbrev0 /* Abbrev offset */
+ .byte 0x4 /* Pointer size */
+dieb: .uleb128 0x1 /* DW_TAG_compile_unit */
+ .long .LASF4 /* DW_AT_producer */
+ .byte 0x4 /* DW_AT_language */
+ .long .LASF5 /* DW_AT_name */
+ .long .LASF6 /* DW_AT_comp_dir */
+ .long 0x0 /* DW_AT_low_pc */
+ .long 0x0 /* DW_AT_high_pc */
+ .long 0x0 /* DW_AT_entry_pc */
+die29: .uleb128 0x2 /* DW_TAG_namespace */
+ .string "N" /* DW_AT_name */
+die32: .uleb128 0x3 /* DW_TAG_class_type */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_declaration */
+die36: .uleb128 0x4 /* DW_TAG_typedef */
+ .string "u" /* DW_AT_name */
+ .long die7e-d /* DW_AT_type */
+die3f: .uleb128 0x5 /* DW_TAG_variable */
+ .string "f" /* DW_AT_name */
+ .long .LASF0 /* DW_AT_MIPS_linkage_name */
+ .long die36-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+die4e: .uleb128 0x5 /* DW_TAG_variable */
+ .string "c" /* DW_AT_name */
+ .long .LASF1 /* DW_AT_MIPS_linkage_name */
+ .long die5e-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+ .byte 0x0
+die5e: .uleb128 0x6 /* DW_TAG_class_type */
+ .long die32-d /* DW_AT_specification */
+ .byte 0x1 /* DW_AT_byte_size */
+die6a: .uleb128 0x7 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_declaration */
+die71: .uleb128 0x8 /* DW_TAG_formal_parameter */
+ .long die8f-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+die77: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e-d /* DW_AT_type */
+ .byte 0x0
+ .byte 0x0
+die7e: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die84-d /* DW_AT_type */
+die84: .uleb128 0xb /* DW_TAG_subroutine_type */
+die89: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die5e-d /* DW_AT_type */
+ .byte 0x0
+die8f: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die5e-d /* DW_AT_type */
+die95: .uleb128 0xc /* DW_TAG_subprogram */
+ .long die6a-d /* DW_AT_specification */
+ .byte 0x2 /* DW_AT_inline */
+die9f: .uleb128 0xd /* DW_TAG_formal_parameter */
+ .long .LASF7 /* DW_AT_name */
+ .long dieaf-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+diea9: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e-d /* DW_AT_type */
+ .byte 0x0
+dieaf: .uleb128 0xe /* DW_TAG_const_type */
+ .long die8f-d /* DW_AT_type */
+dieb4: .uleb128 0xf /* DW_TAG_subprogram */
+ .long die95-d /* DW_AT_abstract_origin */
+ .long _ZN1N1cE /* DW_AT_low_pc */
+ .long _ZN1N1cE /* DW_AT_high_pc */
+diec9: .uleb128 0x10 /* DW_TAG_subprogram */
+ .long die9f-d /* DW_AT_abstract_origin */
+ .byte 2f-1f /* DW_AT_location */
+1:
+ .byte 0x50 /* DW_OP_reg0 */
+2:
+died1: .uleb128 0x10 /* DW_TAG_formal_parameter */
+ .long diea9-d /* DW_AT_abstract_origin */
+ .byte 2f-1f /* DW_AT_location */
+1:
+ .byte 0x51 /* DW_OP_reg1 */
+2:
+ .byte 0x0
+dieda: .uleb128 0x11 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .long .LASF8 /* DW_AT_name */
+ .long dief2-d /* DW_AT_type */
+ .long _ZN1N1cE /* DW_AT_low_pc */
+ .long _ZN1N1cE /* DW_AT_high_pc */
+dief2: .uleb128 0x12 /* DW_TAG_base_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .byte 0x5 /* DW_AT_encoding */
+ .string "int" /* DW_AT_name */
+die149: .uleb128 0x16 /* DW_TAG_variable */
+ .long die4e-d /* DW_AT_specification */
+ .byte 0x5 /* DW_AT_location */
+ .byte 0x3
+ .long _ZN1N1cE
+ .byte 0x0
+.Ldebug_info_end:
+ .section .debug_abbrev
+.Ldebug_abbrev0:
+ .uleb128 0x1 /* abbrev code*/
+ .uleb128 0x11 /* DW_TAG_compile_unit */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x25 /* DW_AT_producer*/
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x13 /* DW_AT_language */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x1b /* DW_AT_comp_dir */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x52 /* DW_AT_entry_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x2 /* abbrev code */
+ .uleb128 0x39 /* DW_TAG_namespace */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x3 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x4 /* abbrev code */
+ .uleb128 0x16 /* DW_TAG_typedef */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x5 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x2007 /* DW_AT_MIPS_linkage_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_TYPE */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x6 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x7 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogra */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x8 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x9 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xa /* abbrev code */
+ .uleb128 0xf /* DW_TAG_pointer_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xb /* abbrev code */
+ .uleb128 0x15 /* DW_TAG_subroutine_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xc /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x20 /* DW_AT_inline */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xd /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xe /* abbrev code */
+ .uleb128 0x26 /* DW_TAG_const_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xf /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x10 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x11 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x12 /* abbrev code */
+ .uleb128 0x24 /* DW_TAG_base_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3e /* DW_AT_encoding */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x16 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .byte 0x0
+ .section .debug_str
+.LASF0:
+ .string "_ZN1N1fE"
+.LASF7:
+ .string "this"
+.LASF6:
+ .string ""
+.LASF8:
+ .string "main"
+.LASF1:
+ .string "_ZN1N1cE"
+.LASF5:
+ .string "pr11465.cc"
+.LASF4:
+ .string "GNU C++ 4.4.2"
+ .ident "GCC: (GNU) 4.4.2"
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-20 20:23 [RFA] Delayed physname computation Keith Seitz
2010-04-21 6:38 ` Jan Kratochvil
@ 2010-04-23 23:03 ` Tom Tromey
2010-04-23 23:34 ` Keith Seitz
2010-04-25 10:33 ` Jan Kratochvil
2 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2010-04-23 23:03 UTC (permalink / raw)
To: Keith Seitz; +Cc: gdb-patches
>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:
Keith> The solution I've implemented is to simply delay processing of method
Keith> physnames until the entire CU has been read/processed.
I read through this and I think it looks good.
I do have some questions, nothing major.
Keith> Unfortunately, this is another example in which the compiler used may
Keith> alter the test outcome. As a result, I've had to hack in a test case
Keith> which is independent of the compiler. I would appreciate special
Keith> attention to the test source file (pr11465.S), which is an edited
Keith> version of gcc's --save-temps output.
This sort of thing is fine, there are other tests made the same way.
I didn't try to read the assembly, but Jan's updated test is ok when
this patch goes in.
Keith> +static void
Keith> +add_to_method_list (struct type *type, int fnfield_index, int index,
Keith> + const char *name, struct die_info *die,
Keith> + struct dwarf2_cu *cu)
This needs some kind of header comment. It can be pretty mild.
Keith> + physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
It would be nice to make all this stuff const-correct. It is definitely
not needed for this patch, I just didn't notice this earlier.
Keith> + /* If methods were found in the partial symbol table, we allocate one
Keith> + big buffer to hold the entire delayed list for the CU. */
Keith> + if (per_cu->num_methods)
Keith> + {
Keith> + cu->method_list
Keith> + = xmalloc (per_cu->num_methods * sizeof (struct delayed_method_info));
Keith> + }
I didn't go dig through the code, so consider this a conditional
request. If we are careful about cleanups here, then this needs a
cleanup; otherwise an error results in a memory leak. If we aren't
already careful, then don't bother, I think we will need to make a pass
through this to make the reader a bit more robust in the face of weird
DWARF. In this case, either file a bug or let me know and I will file
one.
Keith> complaint (&symfile_complaints, _("member function type missing for '%s'"),
Keith> - physname);
Keith> + dwarf2_physname (fieldname, die, cu));
Can this call to dwarf2_physname exhibit the problem that this patch is
trying to circumvent?
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-21 6:38 ` Jan Kratochvil
@ 2010-04-23 23:04 ` Tom Tromey
0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2010-04-23 23:04 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: Keith Seitz, gdb-patches
>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
Jan> testsuite/
Jan> 2010-04-21 Keith Seitz <keiths@redhat.com>
Jan> Jan Kratochvil <jan.kratochvil@redhat.com>
Jan> * gdb.dwarf2/pr11465.exp: New test.
Jan> * gdb.dwarf2/pr11465.S: New file.
For the record, this is ok when Keith's patch is ok.
I think the two should be merged into a single commit.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-23 23:03 ` Tom Tromey
@ 2010-04-23 23:34 ` Keith Seitz
2010-04-26 18:38 ` Tom Tromey
0 siblings, 1 reply; 9+ messages in thread
From: Keith Seitz @ 2010-04-23 23:34 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches
On 04/23/2010 04:03 PM, Tom Tromey wrote:
> Keith> +static void
> Keith> +add_to_method_list (struct type *type, int fnfield_index, int index,
> Keith> + const char *name, struct die_info *die,
> Keith> + struct dwarf2_cu *cu)
>
> This needs some kind of header comment. It can be pretty mild.
Done.
> Keith> + physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
>
> It would be nice to make all this stuff const-correct. It is definitely
> not needed for this patch, I just didn't notice this earlier.
I'll add that to my immediate TODO list.
> I didn't go dig through the code, so consider this a conditional
> request. If we are careful about cleanups here, then this needs a
> cleanup; otherwise an error results in a memory leak. If we aren't
> already careful, then don't bother, I think we will need to make a pass
> through this to make the reader a bit more robust in the face of weird
> DWARF. In this case, either file a bug or let me know and I will file
> one.
Yeah, I wasn't 100% sure whether this needed a cleanup, either.
Nonetheless, we have two options, catch any errors (which I think was
suggested in another thread for a different problem) or add a cleanup. A
little paranoia can't hurt that much. If you have a preference, I'll
implement that.
> Keith> complaint (&symfile_complaints, _("member function type missing for '%s'"),
> Keith> - physname);
> Keith> + dwarf2_physname (fieldname, die, cu));
>
> Can this call to dwarf2_physname exhibit the problem that this patch is
> trying to circumvent?
Unfortunately, it very well could. I guess it would be almost as useful
if this called dwarf2_fullname instead. What do you think?
Keith
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-20 20:23 [RFA] Delayed physname computation Keith Seitz
2010-04-21 6:38 ` Jan Kratochvil
2010-04-23 23:03 ` Tom Tromey
@ 2010-04-25 10:33 ` Jan Kratochvil
2 siblings, 0 replies; 9+ messages in thread
From: Jan Kratochvil @ 2010-04-25 10:33 UTC (permalink / raw)
To: Keith Seitz; +Cc: gdb-patches
Hi Keith,
there is a regression on HEAD + this patch on various files incl.:
wget -q -O - http://kojipkgs.fedoraproject.org/packages/exempi/2.1.0/4.fc12/x86_64/exempi-debuginfo-2.1.0-4.fc12.x86_64.rpm | rpm2cpio - | cpio -idv ./usr/lib/debug/usr/lib64/libexempi.so.3.2.0.debug; ./gdb -q -nx -readnow ./usr/lib/debug/usr/lib64/libexempi.so.3.2.0.debug
./usr/lib/debug/usr/lib64/libexempi.so.3.2.0.debug
14255 blocks
Reading symbols from .../usr/lib/debug/usr/lib64/libexempi.so.3.2.0.debug...expanding to full symbols...dwarf2read.c:3168: internal-error: add_to_method_list: Assertion `cu->method_index < cu->per_cu->num_methods' failed.
A problem internal to GDB has been detected,
Bugreports by Eric Alexander and leoncogs.
Regards,
Jan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-23 23:34 ` Keith Seitz
@ 2010-04-26 18:38 ` Tom Tromey
2010-05-11 21:18 ` Keith Seitz
0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2010-04-26 18:38 UTC (permalink / raw)
To: Keith Seitz; +Cc: gdb-patches
>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:
Keith> Yeah, I wasn't 100% sure whether this needed a cleanup,
Keith> either. Nonetheless, we have two options, catch any errors (which I
Keith> think was suggested in another thread for a different problem) or add
Keith> a cleanup. A little paranoia can't hurt that much. If you have a
Keith> preference, I'll implement that.
One of us can handle it in a followup patch.
>> Can this call to dwarf2_physname exhibit the problem that this patch is
>> trying to circumvent?
Keith> Unfortunately, it very well could. I guess it would be almost as
Keith> useful if this called dwarf2_fullname instead. What do you think?
Yeah. I think it is important for the error case not to crash.
Printing something useful is good, maybe even the CU+DIE would be
enough.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-04-26 18:38 ` Tom Tromey
@ 2010-05-11 21:18 ` Keith Seitz
2010-06-04 22:37 ` Tom Tromey
0 siblings, 1 reply; 9+ messages in thread
From: Keith Seitz @ 2010-05-11 21:18 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2695 bytes --]
I'm attaching the revised version of this patch, which implements your
requests. I am also attaching a related patch (more below).
On 04/26/2010 11:38 AM, Tom Tromey wrote:
>>>>>> "Keith" == Keith Seitz<keiths@redhat.com> writes:
>
> Keith> Yeah, I wasn't 100% sure whether this needed a cleanup,
> Keith> either. Nonetheless, we have two options, catch any errors (which I
> Keith> think was suggested in another thread for a different problem) or add
> Keith> a cleanup. A little paranoia can't hurt that much. If you have a
> Keith> preference, I'll implement that.
>
> One of us can handle it in a followup patch.
I've added a cleanup for this.
>>> Can this call to dwarf2_physname exhibit the problem that this patch is
>>> trying to circumvent?
>
> Keith> Unfortunately, it very well could. I guess it would be almost as
> Keith> useful if this called dwarf2_fullname instead. What do you think?
>
> Yeah. I think it is important for the error case not to crash.
> Printing something useful is good, maybe even the CU+DIE would be
> enough.
I've change this to call dwarf2_full_name, which should tell us
everything except any overload information -- more than enough, IMO, for
a developer to track down the underlying cause.
Now for the "new" part. Fedora testing has revealed a problem with the
optimization that this delayed physname patch uses (allocating all the
memory at once instead of piecemeal). The assert in add_to_method_list
could be triggered.
This was happening because, for some code, like that below, gdb would
call dwarf2_full_name (and determine_prefix) while reading in a specific
DIE, which would then eventually try to read in the same DIE's type.
This resulted in add_to_method_list being called twice for the same DIE
and gdb would assert.
Here's an example that exhibits this "problem" (which I dub an obstack
"leak" because we might end up attempting to allocate/assign two
different struct type's for the same DIE):
class a
{
private:
class b
{
public:
b () { }
};
std::vector<b> list;
};
If you put a printf in set_die_type, you'll see that this function is
called twice (with different type structs) for the same DIE.
Since there is no way to detect/trigger this in gdb without the delayed
physname patch, there seems little point IMO in testing specifically for
this. However it would be trivial for me to write up a testcase for
this. Just say the word.
Keith
ChangeLog (for the obstack leak patch)
2010-05-11 Keith Seitz <keiths@redhat.com>
* dwarf2read.c (read_structure_type): Check if the current
DIE's type was already completed after dwarf2_full_name
was called.
[-- Attachment #2: delayed_physnames-2.patch --]
[-- Type: text/plain, Size: 22453 bytes --]
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.383
diff -u -p -r1.383 dwarf2read.c
--- dwarf2read.c 8 May 2010 04:58:45 -0000 1.383
+++ dwarf2read.c 11 May 2010 20:46:22 -0000
@@ -215,6 +215,26 @@ struct comp_unit_head
unsigned int first_die_offset;
};
+/* Type used for delaying computation of method physnames.
+ See comments for compute_delayed_physnames. */
+struct delayed_method_info
+{
+ /* The type to which the method is attached, i.e., its parent class. */
+ struct type *type;
+
+ /* The index of the method in the type's function fieldlists. */
+ int fnfield_index;
+
+ /* The index of the method in the fieldlist. */
+ int index;
+
+ /* The name of the DIE. */
+ const char *name;
+
+ /* The DIE associated with this method. */
+ struct die_info *die;
+};
+
/* Internal state when decoding a particular compilation unit. */
struct dwarf2_cu
{
@@ -293,6 +313,11 @@ struct dwarf2_cu
/* Header data from the line table, during full symbol processing. */
struct line_header *line_header;
+ /* A list of methods which need to have physnames computed
+ after all type information has been read. */
+ int method_index;
+ struct delayed_method_info *method_list;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
@@ -350,6 +375,10 @@ struct dwarf2_per_cu_data
or NULL for partial units (which do not have an associated
symtab). */
struct partial_symtab *psymtab;
+
+ /* The total number of methods found in the CU. This field is
+ used to allocate memory for delayed physname processing. */
+ int num_methods;
};
/* Entry in the signatured_types hash table. */
@@ -1121,6 +1150,9 @@ static void dwarf2_clear_marks (struct d
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
+static const char *dwarf2_physname (char *name, struct die_info *die,
+ struct dwarf2_cu *cu);
+
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something. */
@@ -2171,6 +2203,24 @@ create_all_comp_units (struct objfile *o
dwarf2_per_objfile->n_comp_units = n_comp_units;
}
+/* Count the number of methods in partial die PDI and its children, if any.
+ The result is recorded in CU. This is used to give an upper bound
+ for the number of slots needed in the delayed method list in the CU.
+ See compute_delayed_physnames. */
+static void
+count_partial_methods (struct partial_die_info *pdi, struct dwarf2_cu *cu)
+{
+ struct partial_die_info *die;
+ for (die = pdi->die_child; die; die = die->die_sibling)
+ {
+ if (die->tag == DW_TAG_subprogram)
+ ++(cu->per_cu->num_methods);
+
+ if (die->has_children)
+ count_partial_methods (die, cu);
+ }
+}
+
/* Process all loaded DIEs for compilation unit CU, starting at
FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
@@ -2206,9 +2256,11 @@ scan_partial_symbols (struct partial_die
case DW_TAG_subprogram:
add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
break;
+ case DW_TAG_union_type:
+ count_partial_methods (pdi, cu);
+ /* fall through */
case DW_TAG_variable:
case DW_TAG_typedef:
- case DW_TAG_union_type:
if (!pdi->is_declaration)
{
add_partial_symbol (pdi, cu);
@@ -2217,6 +2269,7 @@ scan_partial_symbols (struct partial_die
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
+ count_partial_methods (pdi, cu);
if (!pdi->is_declaration)
{
add_partial_symbol (pdi, cu);
@@ -2565,6 +2618,7 @@ add_partial_subprogram (struct partial_d
{
if (pdi->tag == DW_TAG_subprogram)
{
+ count_partial_methods (pdi, cu);
if (pdi->has_pc_info)
{
if (pdi->lowpc < *lowpc)
@@ -3091,6 +3145,42 @@ load_full_comp_unit (struct dwarf2_per_c
discard_cleanups (free_cu_cleanup);
}
+/* Add a DIE to the delayed physname list. */
+static void
+add_to_method_list (struct type *type, int fnfield_index, int index,
+ const char *name, struct die_info *die,
+ struct dwarf2_cu *cu)
+{
+ struct delayed_method_info *mi;
+ gdb_assert (cu->method_index < cu->per_cu->num_methods);
+ mi = &cu->method_list[cu->method_index++];
+ mi->type = type;
+ mi->fnfield_index = fnfield_index;
+ mi->index = index;
+ mi->name = name;
+ mi->die = die;
+}
+
+/* Compute the physnames of any methods on the CU's method list.
+
+ The computation of method physnames is delayed in order to avoid the
+ (bad) condition that one of the method's formal parameters is of an as yet
+ incomplete type. */
+static void
+compute_delayed_physnames (struct dwarf2_cu *cu)
+{
+ int i;
+ for (i = 0; i < cu->method_index; ++i)
+ {
+ char *physname;
+ struct delayed_method_info *mi = &cu->method_list[i];
+ struct fn_fieldlist *fn_flp
+ = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
+ physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+ fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+ }
+}
+
/* Generate full symbol information for PST and CU, whose DIEs have
already been loaded into memory. */
@@ -3102,7 +3192,7 @@ process_full_comp_unit (struct dwarf2_pe
struct objfile *objfile = pst->objfile;
CORE_ADDR lowpc, highpc;
struct symtab *symtab;
- struct cleanup *back_to;
+ struct cleanup *back_to, *delayed_list_cleanup;
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -3112,11 +3202,31 @@ process_full_comp_unit (struct dwarf2_pe
cu->list_in_scope = &file_symbols;
+ /* If methods were found in the partial symbol table, we allocate one
+ big buffer to hold the entire delayed list for the CU. */
+ if (per_cu->num_methods)
+ {
+ cu->method_list
+ = xmalloc (per_cu->num_methods * sizeof (struct delayed_method_info));
+ delayed_list_cleanup = make_cleanup (xfree, cu->method_list);
+ }
+
dwarf2_find_base_address (cu->dies, cu);
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
+ /* Now that we have processed all the DIEs in the CU, all the types
+ should be complete, and it should now be safe to compute all of the
+ physnames. */
+ if (per_cu->num_methods)
+ {
+ compute_delayed_physnames (cu);
+ do_cleanups (delayed_list_cleanup);
+ delayed_list_cleanup = NULL;
+ cu->method_list = NULL;
+ }
+
/* Some compilers don't define a DW_AT_high_pc attribute for the
compilation unit. If the DW_AT_high_pc is missing, synthesize
it, by scanning the DIE's below the compilation unit. */
@@ -4739,7 +4849,6 @@ dwarf2_add_member_fn (struct field_info
int i;
struct fn_field *fnp;
char *fieldname;
- char *physname;
struct nextfnfield *new_fnfield;
struct type *this_type;
@@ -4751,9 +4860,6 @@ dwarf2_add_member_fn (struct field_info
if (fieldname == NULL)
return;
- /* Get the mangled name. */
- physname = (char *) dwarf2_physname (fieldname, die, cu);
-
/* Look up member function name in fieldlist. */
for (i = 0; i < fip->nfnfields; i++)
{
@@ -4779,7 +4885,7 @@ dwarf2_add_member_fn (struct field_info
flp->name = fieldname;
flp->length = 0;
flp->head = NULL;
- fip->nfnfields++;
+ i = fip->nfnfields++;
}
/* Create a new member function field and chain it to the field list
@@ -4793,9 +4899,19 @@ dwarf2_add_member_fn (struct field_info
/* Fill in the member function field info. */
fnp = &new_fnfield->fnfield;
- /* The name is already allocated along with this objfile, so we don't
- need to duplicate it for the type. */
- fnp->physname = physname ? physname : "";
+
+ /* Delay processing of the physname until later. */
+ if (cu->language == language_cplus || cu->language == language_java)
+ {
+ add_to_method_list (type, i, flp->length - 1, fieldname,
+ die, cu);
+ }
+ else
+ {
+ char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+ fnp->physname = physname ? physname : "";
+ }
+
fnp->type = alloc_type (objfile);
this_type = read_type_die (die, cu);
if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
@@ -4821,7 +4937,7 @@ dwarf2_add_member_fn (struct field_info
}
else
complaint (&symfile_complaints, _("member function type missing for '%s'"),
- physname);
+ dwarf2_full_name (fieldname, die, cu));
/* Get fcontext from DW_AT_containing_type if present. */
if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
@@ -6758,7 +6874,9 @@ load_partial_dies (bfd *abfd, gdb_byte *
|| last_die->tag == DW_TAG_interface_type
|| last_die->tag == DW_TAG_structure_type
|| last_die->tag == DW_TAG_union_type))
- || (cu->language == language_ada
+ || ((cu->language == language_ada
+ || cu->language == language_cplus
+ || cu->language == language_java)
&& (last_die->tag == DW_TAG_subprogram
|| last_die->tag == DW_TAG_lexical_block))))
{
Index: testsuite/gdb.dwarf2/pr11465.exp
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.exp
diff -N testsuite/gdb.dwarf2/pr11465.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.exp 11 May 2010 20:46:22 -0000
@@ -0,0 +1,39 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+ && ![istarget *-*-gnu*]
+ && ![istarget *-*-elf*]
+ && ![istarget *-*-openbsd*]
+ && ![istarget arm-*-eabi*]
+ && ![istarget powerpc-*-eabi*]} {
+ return 0
+}
+
+set testfile "pr11465"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+set binfile ${objdir}/${subdir}/${executable}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+ return -1
+}
+
+clean_restart $executable
+
+# Test delayed physname computations
+gdb_test "p N::c.C" { = {void \(N::C \*, void \(\*\)\(N::C\)\)}.*}
Index: testsuite/gdb.dwarf2/pr11465.S
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.S
diff -N testsuite/gdb.dwarf2/pr11465.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.S 11 May 2010 20:46:22 -0000
@@ -0,0 +1,355 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Compiled from:
+
+ namespace N
+ {
+ class C
+ {
+ public:
+ typedef void (*t) (C);
+ C (t) {}
+ };
+ typedef C::t u;
+ u f;
+ C c (f);
+ };
+
+ int
+ main ()
+ {
+ return 0;
+ }
+*/
+
+ .text
+_ZN1N1cE:
+ .section .debug_info
+d:
+ .long .Ldebug_info_end - 1f /* Length of CU info */
+1:
+ .2byte 0x2 /* DWARF version number */
+ .long .Ldebug_abbrev0 /* Abbrev offset */
+ .byte 0x4 /* Pointer size */
+dieb: .uleb128 0x1 /* DW_TAG_compile_unit */
+ .long .LASF4 /* DW_AT_producer */
+ .byte 0x4 /* DW_AT_language */
+ .long .LASF5 /* DW_AT_name */
+ .long .LASF6 /* DW_AT_comp_dir */
+ .long 0x0 /* DW_AT_low_pc */
+ .long 0x0 /* DW_AT_high_pc */
+ .long 0x0 /* DW_AT_entry_pc */
+die29: .uleb128 0x2 /* DW_TAG_namespace */
+ .string "N" /* DW_AT_name */
+die32: .uleb128 0x3 /* DW_TAG_class_type */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_declaration */
+die36: .uleb128 0x4 /* DW_TAG_typedef */
+ .string "u" /* DW_AT_name */
+ .long die7e-d /* DW_AT_type */
+die3f: .uleb128 0x5 /* DW_TAG_variable */
+ .string "f" /* DW_AT_name */
+ .long .LASF0 /* DW_AT_MIPS_linkage_name */
+ .long die36-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+die4e: .uleb128 0x5 /* DW_TAG_variable */
+ .string "c" /* DW_AT_name */
+ .long .LASF1 /* DW_AT_MIPS_linkage_name */
+ .long die5e-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_external */
+ .byte 0x1 /* DW_AT_declaration */
+ .byte 0x0
+die5e: .uleb128 0x6 /* DW_TAG_class_type */
+ .long die32-d /* DW_AT_specification */
+ .byte 0x1 /* DW_AT_byte_size */
+die6a: .uleb128 0x7 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .string "C" /* DW_AT_name */
+ .byte 0x1 /* DW_AT_declaration */
+die71: .uleb128 0x8 /* DW_TAG_formal_parameter */
+ .long die8f-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+die77: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e-d /* DW_AT_type */
+ .byte 0x0
+ .byte 0x0
+die7e: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die84-d /* DW_AT_type */
+die84: .uleb128 0xb /* DW_TAG_subroutine_type */
+die89: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die5e-d /* DW_AT_type */
+ .byte 0x0
+die8f: .uleb128 0xa /* DW_TAG_pointer_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .long die5e-d /* DW_AT_type */
+die95: .uleb128 0xc /* DW_TAG_subprogram */
+ .long die6a-d /* DW_AT_specification */
+ .byte 0x2 /* DW_AT_inline */
+die9f: .uleb128 0xd /* DW_TAG_formal_parameter */
+ .long .LASF7 /* DW_AT_name */
+ .long dieaf-d /* DW_AT_type */
+ .byte 0x1 /* DW_AT_artificial */
+diea9: .uleb128 0x9 /* DW_TAG_formal_parameter */
+ .long die7e-d /* DW_AT_type */
+ .byte 0x0
+dieaf: .uleb128 0xe /* DW_TAG_const_type */
+ .long die8f-d /* DW_AT_type */
+dieb4: .uleb128 0xf /* DW_TAG_subprogram */
+ .long die95-d /* DW_AT_abstract_origin */
+ .long _ZN1N1cE /* DW_AT_low_pc */
+ .long _ZN1N1cE /* DW_AT_high_pc */
+diec9: .uleb128 0x10 /* DW_TAG_subprogram */
+ .long die9f-d /* DW_AT_abstract_origin */
+ .byte 2f-1f /* DW_AT_location */
+1:
+ .byte 0x50 /* DW_OP_reg0 */
+2:
+died1: .uleb128 0x10 /* DW_TAG_formal_parameter */
+ .long diea9-d /* DW_AT_abstract_origin */
+ .byte 2f-1f /* DW_AT_location */
+1:
+ .byte 0x51 /* DW_OP_reg1 */
+2:
+ .byte 0x0
+dieda: .uleb128 0x11 /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_AT_external */
+ .long .LASF8 /* DW_AT_name */
+ .long dief2-d /* DW_AT_type */
+ .long _ZN1N1cE /* DW_AT_low_pc */
+ .long _ZN1N1cE /* DW_AT_high_pc */
+dief2: .uleb128 0x12 /* DW_TAG_base_type */
+ .byte 0x4 /* DW_AT_byte_size */
+ .byte 0x5 /* DW_AT_encoding */
+ .string "int" /* DW_AT_name */
+die149: .uleb128 0x16 /* DW_TAG_variable */
+ .long die4e-d /* DW_AT_specification */
+ .byte 0x5 /* DW_AT_location */
+ .byte 0x3
+ .long _ZN1N1cE
+ .byte 0x0
+.Ldebug_info_end:
+ .section .debug_abbrev
+.Ldebug_abbrev0:
+ .uleb128 0x1 /* abbrev code*/
+ .uleb128 0x11 /* DW_TAG_compile_unit */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x25 /* DW_AT_producer*/
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x13 /* DW_AT_language */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x1b /* DW_AT_comp_dir */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x52 /* DW_AT_entry_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x2 /* abbrev code */
+ .uleb128 0x39 /* DW_TAG_namespace */
+ .byte 0x1 /* DW_children_yes */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x3 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x4 /* abbrev code */
+ .uleb128 0x16 /* DW_TAG_typedef */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x5 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x2007 /* DW_AT_MIPS_linkage_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_TYPE */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x6 /* abbrev code */
+ .uleb128 0x2 /* DW_TAG_class_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x7 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogra */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x3c /* DW_AT_declaration */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x8 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x9 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xa /* abbrev code */
+ .uleb128 0xf /* DW_TAG_pointer_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xb /* abbrev code */
+ .uleb128 0x15 /* DW_TAG_subroutine_type */
+ .byte 0x1 /* DW_has_children_yes */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xc /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x20 /* DW_AT_inline */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xd /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x34 /* DW_AT_artificial */
+ .uleb128 0xc /* DW_FORM_flag */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xe /* abbrev code */
+ .uleb128 0x26 /* DW_TAG_const_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xf /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x1 /* DW_has_children_yes */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x10 /* abbrev code */
+ .uleb128 0x5 /* DW_TAG_formal_parameter */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x31 /* DW_AT_abstract_origin */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x11 /* abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0xe /* DW_FORM_strp */
+ .uleb128 0x49 /* DW_AT_type */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x12 /* abbrev code */
+ .uleb128 0x24 /* DW_TAG_base_type */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0xb /* DW_AT_byte_size */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3e /* DW_AT_encoding */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x16 /* abbrev code */
+ .uleb128 0x34 /* DW_TAG_variable */
+ .byte 0x0 /* DW_has_children_no */
+ .uleb128 0x47 /* DW_AT_specification */
+ .uleb128 0x13 /* DW_FORM_ref4 */
+ .uleb128 0x2 /* DW_AT_location */
+ .uleb128 0xa /* DW_FORM_block1 */
+ .byte 0x0
+ .byte 0x0
+ .byte 0x0
+ .section .debug_str
+.LASF0:
+ .string "_ZN1N1fE"
+.LASF7:
+ .string "this"
+.LASF6:
+ .string ""
+.LASF8:
+ .string "main"
+.LASF1:
+ .string "_ZN1N1cE"
+.LASF5:
+ .string "pr11465.cc"
+.LASF4:
+ .string "GNU C++ 4.4.2"
+ .ident "GCC: (GNU) 4.4.2"
[-- Attachment #3: obstack-leak.patch --]
[-- Type: text/plain, Size: 531 bytes --]
--- dwarf2read.c.orig 2010-05-11 13:46:27.922551500 -0700
+++ dwarf2read.c 2010-05-11 13:46:32.198710619 -0700
@@ -5179,6 +5179,11 @@ read_structure_type (struct die_info *di
if (die->tag == DW_TAG_structure_type
|| die->tag == DW_TAG_class_type)
TYPE_NAME (type) = TYPE_TAG_NAME (type);
+
+ /* dwarf2_full_name might have already finished building the DIE's
+ type. If so, there is no need to continue. */
+ if (get_die_type (die, cu) != NULL)
+ return get_die_type (die, cu);
}
else
{
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Delayed physname computation
2010-05-11 21:18 ` Keith Seitz
@ 2010-06-04 22:37 ` Tom Tromey
0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2010-06-04 22:37 UTC (permalink / raw)
To: Keith Seitz; +Cc: gdb-patches
>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:
Keith> If you put a printf in set_die_type, you'll see that this function is
Keith> called twice (with different type structs) for the same DIE.
This part seems quite weird to me.
But maybe the only real fix for it would be two passes over the DIEs, or
something equally horrible.
Keith> Since there is no way to detect/trigger this in gdb without the
Keith> delayed physname patch, there seems little point IMO in testing
Keith> specifically for this. However it would be trivial for me to write up
Keith> a testcase for this. Just say the word.
I think a test case for this would be good, just to prevent regressions
in the case where someone tries to remove code that looks weird to them.
Both of these patches are ok. Thanks, and sorry for the delay in
reviewing them.
Keith> + physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
It would be nice to const-correct enough so that we could remove these
casts. I'm not asking you to do it though :-)
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-06-04 22:37 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-20 20:23 [RFA] Delayed physname computation Keith Seitz
2010-04-21 6:38 ` Jan Kratochvil
2010-04-23 23:04 ` Tom Tromey
2010-04-23 23:03 ` Tom Tromey
2010-04-23 23:34 ` Keith Seitz
2010-04-26 18:38 ` Tom Tromey
2010-05-11 21:18 ` Keith Seitz
2010-06-04 22:37 ` Tom Tromey
2010-04-25 10:33 ` Jan Kratochvil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).