[ This might be a duplicate of PR14148. ] Building trunk dwz with trunk gcc and CFLAGS="-O0 -ggdb3", I get with trunk gdb: ... $ gdb -batch -ex "break dwz" -ex run -ex finish -ex "ptype res" -ex "ptype struct file_result" --args ./build/dwz Breakpoint 1 at 0x415e40: file /data/dwz/build/../src/dwz.c, line 10982. Breakpoint 1, dwz (file=0x41e94c "a.out", outfile=0x0, res=0x7fffffffdb10, resa=0x0, files=0x0) at /data/dwz/build/../src/dwz.c:10982 10982 res->res = -1; /data/dwz/build/dwz: Failed to open input file a.out: No such file or directory 0x0000000000401e6a in main (argc=1, argv=0x7fffffffdc48) at /data/dwz/build/../src/dwz.c:11922 11922 ret = dwz (optind == argc ? "a.out" : argv[optind], outfile, Value returned is $1 = 1 type = struct file_result { int res; dev_t dev; ino_t ino; nlink_t nlink; } type = struct file_result { int res; dev_t dev; ino_t ino; nlink_t nlink; } ... and with CFLAGS="-O0 -ggdb3 -fdebug-types-section" instead I get: ... $ ~/gdb_versions/devel/gdb -batch -ex "break dwz" -ex run -ex finish -ex "ptype res" -ex "ptype struct file_result" --args ./build/dwz Breakpoint 1 at 0x415e40: file /data/dwz/build/../src/dwz.c, line 10982. Breakpoint 1, dwz (file=0x41e94c "a.out", outfile=0x0, res=0x7fffffffdb10, resa=0x0, files=0x0) at /data/dwz/build/../src/dwz.c:10982 10982 res->res = -1; /data/dwz/build/dwz: Failed to open input file a.out: No such file or directory 0x0000000000401e6a in main (argc=1, argv=0x7fffffffdc48) at /data/dwz/build/../src/dwz.c:11922 11922 ret = dwz (optind == argc ? "a.out" : argv[optind], outfile, Value returned is $1 = 1 type = struct file_result { int res; dev_t dev; ino_t ino; nlink_t nlink; } No struct type named file_result. ... So there's: ... Compilation Unit @ offset 0x0: Length: 0xb7 (32-bit) Version: 4 Abbrev Offset: 0x64 Pointer Size: 8 Signature: 0x314134da8877517a Type Offset: 0x1d <0><17>: Abbrev Number: 1 (DW_TAG_type_unit) <18> DW_AT_language : 12 (ANSI C99) <19> DW_AT_stmt_list : 0xe9 <1><1d>: Abbrev Number: 2 (DW_TAG_structure_type) <1e> DW_AT_name : (indirect string, offset: 0x13163): file_result ... and: ... <1><e4b7>: Abbrev Number: 51 (DW_TAG_structure_type) <e4b8> DW_AT_signature : signature: 0x314134da8877517a ... which is the type of res: ... <2><c65>: Abbrev Number: 64 (DW_TAG_variable) <c66> DW_AT_name : res <c6a> DW_AT_decl_file : 1 <c6b> DW_AT_decl_line : 11845 <c6d> DW_AT_decl_column : 22 <c6e> DW_AT_type : <0xe4b7> <c72> DW_AT_location : 3 byte block: 91 e0 7d (DW_OP_fbreg: -288) ... but struct file_result as a toplevel type goes missing.
The problem is that this die: ... <1><123d>: Abbrev Number: 67 (DW_TAG_structure_type) <123e> DW_AT_name : (indirect string, offset: 0x4980): file_result <1242> DW_AT_signature : signature: 0x314134da8877517a <124a> DW_AT_declaration : 1 ... is skipped here in process_structure_scope: ... /* Do not consider external references. According to the DWARF standard, these DIEs are identified by the fact that they have no byte_size attribute, and a declaration attribute. */ if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL || !die_is_declaration (die, cu)) { ... The comment references the DWARF standard (v4, 5.5.1 Structure, Union and Class Type Entries): ... An incomplete structure, union or class type is represented by a structure, union or class entry that does not have a byte size attribute and that has a DW_AT_declaration attribute. ... But the code does not handle the following bit: ... If the complete declaration of a type has been placed in a separate type unit (see Section 3.1.3), an incomplete declaration of that type in the compilation unit may provide the unique 64-bit signature of the type using a DW_AT_signature attribute. ... Using this tentative patch: ... diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index e1829358aa..7f82ce5a33 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -20101,7 +20101,8 @@ die_is_declaration (struct die_info *die, struct dwarf2_cu *cu) to a different DIE referenced by the specification attribute, even though the given DIE does not have a declaration attribute. */ return (dwarf2_flag_true_p (die, DW_AT_declaration, cu) - && dwarf2_attr (die, DW_AT_specification, cu) == NULL); + && dwarf2_attr (die, DW_AT_specification, cu) == NULL + && dwarf2_attr (die, DW_AT_signature, cu) == NULL); } /* Return the die giving the specification for DIE, if there is ... I get the expected: ... $ ./gdb -batch -ex "break dwz" -ex run -ex finish -ex "ptype res" -ex "ptype struct file_result" --args ./build/dwz Breakpoint 1 at 0x425d9a: file /data/dwz/build/../src/dwz.c, line 10984. Breakpoint 1, dwz (file=0x431d31 "a.out", outfile=0x0, res=0x7fffffffda70, resa=0x0, files=0x0) at /data/dwz/build/../src/dwz.c:10984 10984 int ret = 0, fd; /data/dwz/build/dwz: Failed to open input file a.out: No such file or directory 0x000000000042887a in main (argc=1, argv=0x7fffffffdc68) at /data/dwz/build/../src/dwz.c:11928 11928 ret = dwz (optind == argc ? "a.out" : argv[optind], outfile, Value returned is $1 = 1 type = struct file_result { int res; dev_t dev; ino_t ino; nlink_t nlink; } type = struct file_result { int res; dev_t dev; ino_t ino; nlink_t nlink; } ...
Regression due to " Set list_in_scope later in DWARF reader": https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=93b8bea4143cafae79076076c64aaa4c46a9b73c
Minimal test-case dwz.c: ... struct foo { int i; }; struct foo var1; struct file_result { int res; }; struct file_result var2; int main (void) { struct file_result res; return 0; } ... compiled like this (either vanilla gcc trunk, or gcc 7.4.0 on openSUSE leap 15.0): ... $ gcc -O0 -ggdb3 -fdebug-types-section src/dwz.c -o build/dwz ... With gdb.ok (gdb-8.2.1), and gdb.bad (master), we get: ... $ for gdb in ./gdb.ok ./gdb.bad ; do \ echo $gdb; \ $gdb \ -readnow \ -batch \ -ex "break main" \ -ex run \ -ex "ptype struct file_result" \ -ex "ptype struct foo" --args build/dwz \ 2>&1 | egrep "file_result|foo"; \ done ./gdb.ok struct file_result { struct foo { ./gdb.bad No struct type named file_result. type = struct foo { ...
Created attachment 12214 [details] Fix for missing top level types with -fdebug-types-section This fixes the issue. The problem is it relies on start_symtab to set list_in_scope, but start_symtab is only called for the first tu that contributes to a symtab. Since each type is in its own tu, only one type goes into the file scope table. Just set it on the other paths too.
Mark, could you send that patch to the gdb-patches@sourceware.org mailing list, as per https://sourceware.org/gdb/wiki/ContributionChecklist ?
(In reply to Christian Biesinger from comment #5) > Mark, could you send that patch to the gdb-patches@sourceware.org mailing > list, as per https://sourceware.org/gdb/wiki/ContributionChecklist ? https://sourceware.org/pipermail/gdb-patches/2020-January/164813.html
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=770479f223ecd1920dd3cc683b05b24af25c4613 commit 770479f223ecd1920dd3cc683b05b24af25c4613 Author: Mark Williams <mark@myosotissp.com> Date: Tue Apr 28 16:12:45 2020 +0200 gdb: Fix toplevel types with -fdebug-types-section When debugging a program compiled with -fdebug-types-section, only the first top-level type in each file is visible to gdb. The problem was caused by moving the assignment to list_in_scope from process_full_comp_unit and process_full_type_unit to start_symtab. This was fine for process_full_comp_unit, because symtabs and comp units are one-to-one. But there can be many type units per symtab (one for each type), and we only call start_symtab for the first one. This adds the necessary assignments on the paths where start_symtab is not called. gdb/Changelog: 2020-04-28 Mark Williams <mark@myosotissp.com> PR gdb/24480 * dwarf2read.c: Add missing assingments to list_in_scope when start_symtab was already called. gdb/testsuite/Changelog: 2020-04-28 Mark Williams <mark@myosotissp.com> PR gdb/24480 * dw4-toplevel-types.exp: Test for top level types. * dw4-toplevel-types.cc: Test for top level types.
*** Bug 25886 has been marked as a duplicate of this bug. ***
I've retested the minimal test-case from comment 3, and can confirm it passes with the committed patch. Patch with test-case committed, marking resolved-fixed.
FTR, the same problem was found, and a similar patch proposed here ( https://sourceware.org/pipermail/gdb/2020-March/000016.html ).