From 71c25deab3d61e4cfbaffc7006704a27d1bc0737 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 31 Mar 2009 20:21:08 +0000 Subject: [PATCH] gdb 2009-03-31 Daniel Jacobowitz Keith Seitz Jan Kratochvil PR gdb/6817 * Makefile.in (dbxread.o): Update. * dbxread.c (read_dbx_symtab): Use cp_canonicalize_string. * dwarf2read.c (GDB_FORM_cached_string): New. (read_partial_die): Use dwarf2_canonicalize_name. (dwarf2_linkage_name): Use dwarf2_name. (dwarf2_canonicalize_name): New. (dwarf2_name): Use dwarf2_canonicalize_name. (dwarf_form_name, dump_die): Handle GDB_FORM_cached_string. * stabsread.c (define_symbol, read_type): Use cp_canonicalize_string. * symtab.c (lookup_symbol_in_language): Canonicalize input before searching. * cp-name-parser.y: operator() requires two parameters, according to libiberty. * minsyms.c (lookup_minimal_symbol): Canonicalize input before searching. * NEWS: Update. gdb/testsuite 2009-03-31 Daniel Jacobowitz Jan Kratochvil PR gdb/931 * gdb.cp/gdb1355.exp (f_li, f_lui, f_si, f_sui): Allow canonical output. * gdb.cp/templates.exp: Allow canonical output. Remove KFAILs for gdb/931. * dw2-strp.S (DW_AT_language): Change to C++. (DW_TAG_variable (name ""), Abbrev code 7, .Lemptyname): New. --- gdb/ChangeLog | 22 +++++++++ gdb/NEWS | 13 ++++++ gdb/cp-name-parser.y | 2 +- gdb/dbxread.c | 40 +++++++++++++---- gdb/dwarf2read.c | 89 ++++++++++++++++++++++++++++++++----- gdb/minsyms.c | 32 ++++++++++++- gdb/stabsread.c | 52 +++++++++++++++++----- gdb/symtab.c | 12 +++++ gdb/testsuite/ChangeLog | 11 +++++ gdb/testsuite/gdb.cp/gdb1355.exp | 8 ++-- gdb/testsuite/gdb.cp/templates.exp | 18 +++----- gdb/testsuite/gdb.dwarf2/dw2-strp.S | 18 +++++++- 12 files changed, 268 insertions(+), 49 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ec689f5..1ff05ab 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2009-03-31 Daniel Jacobowitz + Keith Seitz + Jan Kratochvil + + PR gdb/6817 + * Makefile.in (dbxread.o): Update. + * dbxread.c (read_dbx_symtab): Use cp_canonicalize_string. + * dwarf2read.c (GDB_FORM_cached_string): New. + (read_partial_die): Use dwarf2_canonicalize_name. + (dwarf2_linkage_name): Use dwarf2_name. + (dwarf2_canonicalize_name): New. + (dwarf2_name): Use dwarf2_canonicalize_name. + (dwarf_form_name, dump_die): Handle GDB_FORM_cached_string. + * stabsread.c (define_symbol, read_type): Use cp_canonicalize_string. + * symtab.c (lookup_symbol_in_language): Canonicalize input before + searching. + * cp-name-parser.y: operator() requires two parameters, + according to libiberty. + * minsyms.c (lookup_minimal_symbol): Canonicalize input + before searching. + * NEWS: Update. + 2009-03-31 Joel Brobecker Provide support for (Ada) task-specific breakpoints. diff --git a/gdb/NEWS b/gdb/NEWS index a8ddd45..589eeed 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -93,6 +93,19 @@ have also been fixed. From the user's standpoint, all unqualified instances of True and False are treated as the standard definitions, regardless of context. +* GDB now parses C++ symbol and type names more flexibly. For +example, given: + + template class C { }; + C c; + +GDB will now correctly handle all of: + + ptype C + ptype C + ptype C + ptype C + * New features in the GDB remote stub, gdbserver - The "--wrapper" command-line argument tells gdbserver to use a diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index 0b5069d..b70ad21 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -499,7 +499,7 @@ operator : OPERATOR NEW | OPERATOR ARROW { $$ = make_operator ("->", 2); } | OPERATOR '(' ')' - { $$ = make_operator ("()", 0); } + { $$ = make_operator ("()", 2); } | OPERATOR '[' ']' { $$ = make_operator ("[]", 2); } ; diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 115bdef..d520266 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1188,6 +1188,8 @@ read_dbx_symtab (struct objfile *objfile) struct internal_nlist nlist; CORE_ADDR text_addr; int text_size; + char *sym_name; + int sym_len; char *namestring; int nsl; @@ -1681,6 +1683,28 @@ pos %d"), if (!p) continue; /* Not a debugging symbol. */ + sym_len = 0; + if (psymtab_language == language_cplus) + { + char *new_name, *name = alloca (p - namestring + 1); + memcpy (name, namestring, p - namestring); + name[p - namestring] = '\0'; + new_name = cp_canonicalize_string (name); + if (new_name != NULL) + { + sym_len = strlen (new_name); + sym_name = obsavestring (new_name, sym_len, + &objfile->objfile_obstack); + xfree (new_name); + } + } + + if (sym_len == 0) + { + sym_name = namestring; + sym_len = p - namestring; + } + /* Main processing section for debugging symbols which the initial read through the symbol tables needs to worry about. If we reach this point, the symbol which we are @@ -1698,7 +1722,7 @@ pos %d"), namestring = gdbarch_static_transform_name (gdbarch, namestring); - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, nlist.n_value, @@ -1710,7 +1734,7 @@ pos %d"), data_sect_index); /* The addresses in these entries are reported to be wrong. See the code that reads 'G's for symtabs. */ - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, nlist.n_value, @@ -1728,7 +1752,7 @@ pos %d"), || (p == namestring + 1 && namestring[0] != ' ')) { - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, STRUCT_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, @@ -1736,7 +1760,7 @@ pos %d"), if (p[2] == 't') { /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, @@ -1749,7 +1773,7 @@ pos %d"), case 't': if (p != namestring) /* a name is there, not just :T... */ { - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, @@ -1829,7 +1853,7 @@ pos %d"), case 'c': /* Constant, e.g. from "const" in Pascal. */ - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, nlist.n_value, 0, psymtab_language, objfile); @@ -1893,7 +1917,7 @@ pos %d"), pst->textlow = nlist.n_value; textlow_not_set = 0; } - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, nlist.n_value, @@ -1961,7 +1985,7 @@ pos %d"), pst->textlow = nlist.n_value; textlow_not_set = 0; } - add_psymbol_to_list (namestring, p - namestring, + add_psymbol_to_list (sym_name, sym_len, VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, nlist.n_value, diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 9ec4efa..9fd2f0c 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -523,6 +523,15 @@ struct attr_abbrev ENUM_BITFIELD(dwarf_form) form : 16; }; +/* Additional GDB-specific attribute forms. */ +enum + { + /* A string which has been updated to GDB's internal + representation (e.g. converted to canonical form) and does not + need to be updated again. */ + GDB_FORM_cached_string = 0xff + }; + /* Attributes have a name and a value */ struct attribute { @@ -993,6 +1002,9 @@ static void process_die (struct die_info *, struct dwarf2_cu *); static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); +static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *, + struct obstack *); + static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); static struct die_info *dwarf2_extension (struct die_info *die, @@ -5946,10 +5958,23 @@ read_partial_die (struct partial_die_info *part_die, switch (attr.name) { case DW_AT_name: - - /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */ - if (part_die->name == NULL) - part_die->name = DW_STRING (&attr); + switch (part_die->tag) + { + case DW_TAG_compile_unit: + /* Compilation units have a DW_AT_name that is a filename, not + a source language identifier. */ + case DW_TAG_enumeration_type: + case DW_TAG_enumerator: + /* These tags always have simple identifiers already; no need + to canonicalize them. */ + part_die->name = DW_STRING (&attr); + break; + default: + part_die->name + = dwarf2_canonicalize_name (DW_STRING (&attr), cu, + &cu->comp_unit_obstack); + break; + } break; case DW_AT_comp_dir: if (part_die->dirname == NULL) @@ -8199,10 +8224,29 @@ dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); - attr = dwarf2_attr (die, DW_AT_name, cu); - if (attr && DW_STRING (attr)) - return DW_STRING (attr); - return NULL; + return dwarf2_name (die, cu); +} + +/* Get name of a die, return NULL if not found. */ + +static char * +dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu, + struct obstack *obstack) +{ + if (name && cu->language == language_cplus) + { + char *canon_name = cp_canonicalize_string (name); + + if (canon_name != NULL) + { + if (strcmp (canon_name, name) != 0) + name = obsavestring (canon_name, strlen (canon_name), + obstack); + xfree (canon_name); + } + } + + return name; } /* Get name of a die, return NULL if not found. */ @@ -8213,9 +8257,29 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; attr = dwarf2_attr (die, DW_AT_name, cu); - if (attr && DW_STRING (attr)) - return DW_STRING (attr); - return NULL; + if (!attr || !DW_STRING (attr)) + return NULL; + + switch (die->tag) + { + case DW_TAG_compile_unit: + /* Compilation units have a DW_AT_name that is a filename, not + a source language identifier. */ + case DW_TAG_enumeration_type: + case DW_TAG_enumerator: + /* These tags always have simple identifiers already; no need + to canonicalize them. */ + return DW_STRING (attr); + default: + if (attr->form != GDB_FORM_cached_string) + { + DW_STRING (attr) + = dwarf2_canonicalize_name (DW_STRING (attr), cu, + &cu->objfile->objfile_obstack); + attr->form = GDB_FORM_cached_string; + } + return DW_STRING (attr); + } } /* Return the die that this die in an extension of, or NULL if there @@ -8710,6 +8774,8 @@ dwarf_form_name (unsigned form) return "DW_FORM_ref_udata"; case DW_FORM_indirect: return "DW_FORM_indirect"; + case GDB_FORM_cached_string: + return "GDB_FORM_cached_string"; default: return "DW_FORM_"; } @@ -9255,6 +9321,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) break; case DW_FORM_string: case DW_FORM_strp: + case GDB_FORM_cached_string: fprintf_unfiltered (f, "string: \"%s\"", DW_STRING (&die->attrs[i]) ? DW_STRING (&die->attrs[i]) : ""); diff --git a/gdb/minsyms.c b/gdb/minsyms.c index bf776b3..e4b0f31 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -48,6 +48,8 @@ #include "value.h" #include "cp-abi.h" #include "target.h" +#include "cp-support.h" +#include "language.h" /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE. At the end, copy them all into one newly allocated location on an objfile's @@ -187,6 +189,9 @@ lookup_minimal_symbol (const char *name, const char *sfile, unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE; + int needtofreename = 0; + const char *modified_name; + if (sfile != NULL) { char *p = strrchr (sfile, '/'); @@ -194,6 +199,18 @@ lookup_minimal_symbol (const char *name, const char *sfile, sfile = p + 1; } + /* For C++, canonicalize the input name. */ + modified_name = name; + if (current_language->la_language == language_cplus) + { + char *cname = cp_canonicalize_string (name); + if (cname) + { + modified_name = cname; + needtofreename = 1; + } + } + for (objfile = object_files; objfile != NULL && found_symbol == NULL; objfile = objfile->next) @@ -218,9 +235,16 @@ lookup_minimal_symbol (const char *name, const char *sfile, int match; if (pass == 1) - match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0; + { + match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), + modified_name) == 0; + } else - match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, name); + { + match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, + modified_name); + } + if (match) { switch (MSYMBOL_TYPE (msymbol)) @@ -259,6 +283,10 @@ lookup_minimal_symbol (const char *name, const char *sfile, } } } + + if (needtofreename) + xfree ((void *) modified_name); + /* External symbols are best. */ if (found_symbol) return found_symbol; diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 2d7eb15..17dfce4 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -589,6 +589,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, int deftype; int synonym = 0; int i; + char *new_name = NULL; /* We would like to eliminate nameless symbols, but keep their types. E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer @@ -683,9 +684,21 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, { normal: SYMBOL_LANGUAGE (sym) = current_subfile->language; - SYMBOL_SET_NAMES (sym, string, p - string, objfile); if (SYMBOL_LANGUAGE (sym) == language_cplus) - cp_scan_for_anonymous_namespaces (sym); + { + char *name = alloca (p - string + 1); + memcpy (name, string, p - string); + name[p - string] = '\0'; + new_name = cp_canonicalize_string (name); + cp_scan_for_anonymous_namespaces (sym); + } + if (new_name != NULL) + { + SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), objfile); + xfree (new_name); + } + else + SYMBOL_SET_NAMES (sym, string, p - string, objfile); } p++; @@ -1519,18 +1532,35 @@ again: if (*p != ':') return error_type (pp, objfile); } - to = type_name = - (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); - - /* Copy the name. */ - from = *pp + 1; - while (from < p) - *to++ = *from++; - *to = '\0'; + type_name = NULL; + if (current_subfile->language == language_cplus) + { + char *new_name, *name = alloca (p - *pp + 1); + memcpy (name, *pp, p - *pp); + name[p - *pp] = '\0'; + new_name = cp_canonicalize_string (name); + if (new_name != NULL) + { + type_name = obsavestring (new_name, strlen (new_name), + &objfile->objfile_obstack); + xfree (new_name); + } + } + if (type_name == NULL) + { + to = type_name = + (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); + + /* Copy the name. */ + from = *pp + 1; + while (from < p) + *to++ = *from++; + *to = '\0'; + } /* Set the pointer ahead of the name which we just read, and the colon. */ - *pp = from + 1; + *pp = p + 1; } /* If this type has already been declared, then reuse the same diff --git a/gdb/symtab.c b/gdb/symtab.c index 7fff68a..622ddd3 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -55,6 +55,7 @@ #include "gdb_stat.h" #include #include "cp-abi.h" +#include "cp-support.h" #include "observer.h" #include "gdb_assert.h" #include "solist.h" @@ -1213,6 +1214,17 @@ lookup_symbol_in_language (const char *name, const struct block *block, modified_name = demangled_name; make_cleanup (xfree, demangled_name); } + else + { + /* If we were given a non-mangled name, canonicalize it + according to the language (so far only for C++). */ + demangled_name = cp_canonicalize_string (name); + if (demangled_name) + { + modified_name = demangled_name; + make_cleanup (xfree, demangled_name); + } + } } else if (lang == language_java) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index cf1378f..016bf54 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2009-03-31 Daniel Jacobowitz + Jan Kratochvil + + PR gdb/931 + * gdb.cp/gdb1355.exp (f_li, f_lui, f_si, f_sui): Allow canonical + output. + * gdb.cp/templates.exp: Allow canonical output. Remove KFAILs + for gdb/931. + * dw2-strp.S (DW_AT_language): Change to C++. + (DW_TAG_variable (name ""), Abbrev code 7, .Lemptyname): New. + 2009-03-31 Joel Brobecker * gdb.ada/tasks: New testcase. diff --git a/gdb/testsuite/gdb.cp/gdb1355.exp b/gdb/testsuite/gdb.cp/gdb1355.exp index 77687a6..8028bce 100644 --- a/gdb/testsuite/gdb.cp/gdb1355.exp +++ b/gdb/testsuite/gdb.cp/gdb1355.exp @@ -68,11 +68,11 @@ set s_tail ".*" set f_i "${ws}int m_int;" set f_c "${ws}char m_char;" -set f_li "${ws}long int m_long_int;" +set f_li "${ws}long( int)? m_long_int;" set f_ui "${ws}unsigned int m_unsigned_int;" -set f_lui "${ws}long unsigned int m_long_unsigned_int;" -set f_si "${ws}short int m_short_int;" -set f_sui "${ws}short unsigned int m_short_unsigned_int;" +set f_lui "${ws}(long unsigned int|unsigned long) m_long_unsigned_int;" +set f_si "${ws}short( int)? m_short_int;" +set f_sui "${ws}(short unsigned int|unsigned short) m_short_unsigned_int;" set f_uc "${ws}unsigned char m_unsigned_char;" set f_f "${ws}float m_float;" set f_d "${ws}double m_double;" diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp index cd9b770..f49caff 100644 --- a/gdb/testsuite/gdb.cp/templates.exp +++ b/gdb/testsuite/gdb.cp/templates.exp @@ -329,13 +329,11 @@ gdb_expect { send_gdb "print Foo::foo\n" gdb_expect { - -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo \\*(| const), int, .*char \\*\\)\\} $hex ::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo::foo" } + -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex ::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo::foo" } -re "No symbol \"Foo\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33. That problem has been - # fixed, but now gdb/931 and gdb/1512 are rearing their ugly - # heads. - kfail "gdb/931" "print Foo::foo" + # This used to be a kfail gdb/33 and then kfail gdb/931. + fail "print Foo::foo" } -re "$gdb_prompt $" { fail "print Foo::foo" } timeout { fail "(timeout) print Foo::foo" } @@ -343,13 +341,11 @@ gdb_expect { send_gdb "print Foo::foo\n" gdb_expect { - -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo \\*(| const), int, .*char \\*\\)\\} $hex ::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo::foo" } + -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex ::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo::foo" } -re "No symbol \"Foo\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33. That problem has been - # fixed, but now gdb/931 and gdb/1512 are rearing their ugly - # heads. - kfail "gdb/931" "print Foo::foo" + # This used to be a kfail gdb/33 and then kfail gdb/931. + fail "print Foo::foo" } -re "$gdb_prompt $" { fail "print Foo::foo" } timeout { fail "(timeout) print Foo::foo" } @@ -459,7 +455,7 @@ send_gdb "ptype quxint\n" gdb_expect { -re "type = class Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } -re "type = class Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } - -re "type = class Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } + -re "type = class Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } -re "type = class Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { kfail "gdb/1512" "ptype quxint" } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-strp.S b/gdb/testsuite/gdb.dwarf2/dw2-strp.S index a1602a5..293cc1b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-strp.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-strp.S @@ -28,7 +28,8 @@ /* CU die */ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ .4byte .Lproducer /* DW_AT_producer */ - .byte 1 /* DW_AT_language (C) */ + /* Use C++ to exploit a bug in parsing DW_AT_name "". */ + .byte 4 /* DW_AT_language (C++) - */ .Larray_type: .uleb128 2 /* Abbrev: DW_TAG_array_type */ @@ -60,6 +61,10 @@ .Lconst_type: .uleb128 6 /* Abbrev: DW_TAG_const_type */ .4byte .Larray_type-.Lcu1_begin/* DW_AT_type */ + + .uleb128 7 /* Abbrev: DW_TAG_variable (name "") */ + .4byte .Lemptyname /* DW_AT_name */ + .byte 0 /* End of children of CU */ .Lcu1_end: @@ -126,6 +131,15 @@ .uleb128 0x13 /* DW_FORM_ref4 */ .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ + + .uleb128 7 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0x0 /* DW_children_no */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0xe /* DW_FORM_strp */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ /* String table */ @@ -140,3 +154,5 @@ .string "a_string" .Lvarcontents: .string "hello world!\n" +.Lemptyname: + .string "" -- 2.7.4