We (myself and Frank Eigler) think we have found a problem with this commit: commit 591cc9fbbfd6d51131c0f1d4a92e7893edcc7a28 Author: Jan Beulich <jbeulich@suse.com> Date: Thu Apr 7 08:18:00 2022 +0200 gas/Dwarf: record functions To help tools like addr2line looking up function names, in particular when dealing with e.g. PE/COFF binaries (linked from ELF objects), where there's no ELF symbol table to fall back to, emit minimalistic information for functions marked as such and having their size specified. ... The GDB community recently encountered a regression when running the GDB testsuite on recent Fedora rawhide (rolling) releases which use binutils-2.39. The log file shows this failure: print /d (int) munmap (4198400, 4096) Invalid cast. (gdb) FAIL: gdb.base/break-main-file-remove-fail.exp: cmdline: get integer valueof "(int) munmap (4198400, 4096)" Running GDB by hand with the testcase binary, I see: (gdb) ptype munmap type = void (void) This explains the reason for the failure: GDB doesn't let us cast a void to an int. Looking at the output (which ends up in the file "syms") produced by doing "maint print symbols syms" in GDB, I see: Symtab for file ../sysdeps/unix/syscall-template.S at 0x1149b90 Compilation directory is /usr/src/debug/glibc-2.36.9000-2.fc38.x86_64/misc Read from object file /lib64/ld-linux-x86-64.so.2 (0xfefbc0) Language: asm ... Blockvector: ... block #000, object at 0x16fd620, 1 syms/buckets in 0x7ffff7feb960..0x7ffff7feb984 ... void munmap(void); block object 0x16fd3a0, 0x7ffff7feb960..0x7ffff7feb984 section .text This tells us the name of the object file from where GDB obtained the symbols / debug info as well as reaffirming the fact that GDB thinks that the return type of munmap is 'void'. (According to its man page, the correct type of munmap should be int munmap(void *addr, size_t length).) Now, looking at "readelf -w /lib64/ld-linux-x86-64.so.2", we can find the CU and DIE for munmap: Compilation Unit @ offset 0x350ac: Length: 0x61 (32-bit) Version: 5 Unit Type: DW_UT_compile (1) Abbrev Offset: 0xa21f Pointer Size: 8 <0><350b8>: Abbrev Number: 1 (DW_TAG_compile_unit) <350b9> DW_AT_stmt_list : 0x1f3fa <350bd> DW_AT_low_pc : 0x21960 <350c5> DW_AT_high_pc : 36 <350c6> DW_AT_name : (indirect string, offset: 0x186a): ../sysdeps/unix/syscall-template.S <350ca> DW_AT_comp_dir : (indirect string, offset: 0x26a9): /usr/src/debug/glibc-2.36.9000-2.fc38.x86_64/misc <350ce> DW_AT_producer : (indirect string, offset: 0x9f1): GNU AS 2.39 <350d2> DW_AT_language : 32769 (MIPS assembler) ... <1><350f2>: Abbrev Number: 2 (DW_TAG_subprogram) <350f3> DW_AT_name : (indirect string, offset: 0x6703): munmap <350f7> DW_AT_external : 0 <350f8> DW_AT_low_pc : 0x21960 <35100> DW_AT_high_pc : 36 Note that there's no DW_AT_type attribute (which would specify the return type) for the munmap subprogram. As I understand it, this causes the return type to be void. In section 3.3.2 of the DWARF 5 doc, it says "Debugging information entries for C void functions should not have an attribute for the return type." However, a potential fix is suggested by section 5.2: "An unspecified (implicit, unknown, ambiguous or nonexistent) type is represented by a debugging information entry with the tag DW_TAG_unspecified_type." Earlier Fedora releases including Fedora 35, 36, and 37 do not have a munmap subprogram in ld-linux-x86-64.so.2. For these releases, "ptype munmap" from within GDB shows "type = <unknown return type> ()". GDB can cast the unknown return type to an int which avoids the "invalid cast" error that we are currently seeing on rawhide. This problem can be reproduced in a suitable environment by building upstream gdb and then, from within the 'gdb' directory, doing: make check TESTS=gdb.base/break-main-file-remove-fail.exp On rawhide, I see the following failures: FAIL: gdb.base/break-main-file-remove-fail.exp: cmdline: get integer valueof "(int) munmap (4198400, 4096)" FAIL: gdb.base/break-main-file-remove-fail.exp: file: get integer valueof "(int) munmap (4198400, 4096)" If you wish to run GDB by hand using the test case for this test, do: ./gdb -q testsuite/outputs/gdb.base/break-main-file-remove-fail/break-main-file-remove-fail Then... (gdb) b start Breakpoint 1 at 0x40113a: file /ironwood1/sourceware-git/rawhide-master/bld/../../worktree-master/gdb/testsuite/gdb.base/break-main-file-remove-fail.c, line 26. (gdb) run Starting program: /mesquite2/sourceware-git/rawhide-master/bld/gdb/testsuite/outputs/gdb.base/break-main-file-remove-fail/break-main-file-remove-fail This GDB supports auto-downloading debuginfo from the following URLs: <https://debuginfod.fedoraproject.org/> Enable debuginfod for this session? (y or [n]) n Debuginfod has been disabled. To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, start () at /ironwood1/sourceware-git/rawhide-master/bld/../../worktree-master/gdb/testsuite/gdb.base/break-main-file-remove-fail.c:26 26 } (gdb) ptype munmap type = void (void) Regarding debuginfod, I see the same result whether it's enabled or not, but not enabling it makes it clear that the problematic debug info isn't coming from anything downloaded by debuginfod.
(In reply to Kevin Buettner from comment #0) > Note that there's no DW_AT_type attribute (which would specify the return > type) for the munmap subprogram. As I understand it, this causes the return > type to be void. In section 3.3.2 of the DWARF 5 doc, it says "Debugging > information entries for C void functions should not have an attribute for > the return type." > > However, a potential fix is suggested by section 5.2: "An unspecified > (implicit, unknown, ambiguous or nonexistent) type is represented by a > debugging information entry with the tag DW_TAG_unspecified_type." Well, that's the route to take then for Dwarf3 and newer, I guess. I don't currently see what we could do about it for Dwarf2, though.
Created attachment 14296 [details] Proposed Patch Hi Kevin, Hi Frank, Is this the sort of patch you had in mind ? I have not regression tested it yet, but I thought that it might be worth checking with you that this is what you were looking for. Cheers Nick
(lgtm on paper!)
(In reply to Nick Clifton from comment #2) > Is this the sort of patch you had in mind ? > > I have not regression tested it yet, but I thought that it might be worth > checking with you that this is what you were looking for. LGTM also.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5578fbf672ee497ea19826edeb509f4cc3e825a8 commit 5578fbf672ee497ea19826edeb509f4cc3e825a8 Author: Nick Clifton <nickc@redhat.com> Date: Thu Aug 25 11:48:00 2022 +0100 GAS: Add a return type tag to DWARF DIEs generated for function symbols. PR 29517 * dwarf2dbg.c (GAS_ABBREV_COMP_UNIT): New defined constant. (GAS_ABBREV_SUBPROG): New defined constant. (GAS_ABBREV_NO_TYPE): New defined constant. (out_debug_abbrev): Use the new defined constants when emitting abbreviation numbers. Generate an abbreviation for an unspecified type. (out_debug_info): Use the new defined constants when referring to abbreviations. Generate a use of the no_type abbreviation. Reference the use when generating DIEs for functions. * testsuite/gas/elf/dwarf-3-func.d: Update to allow for newly extended output from the assembler. * testsuite/gas/elf/dwarf-5-func-global.d: Likewise. * testsuite/gas/elf/dwarf-5-func-local.d: Likewise. * testsuite/gas/elf/dwarf-5-func.d: Likewise.
Right - I have applied the patch.
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1d45d90934b10862c00a22bcf4075815a785001b commit 1d45d90934b10862c00a22bcf4075815a785001b Author: Tom de Vries <tdevries@suse.de> Date: Mon Oct 16 16:32:28 2023 +0200 [gdb/symtab] Work around PR gas/29517 When using glibc debuginfo generated with gas 2.39, we run into PR gas/29517: ... $ gdb -q -batch a.out -ex start -ex "p (char *)strstr (\"haha\", \"ah\")" Temporary breakpoint 1 at 0x40051b: file hello.c, line 6. Temporary breakpoint 1, main () at hello.c:6 6 printf ("hello\n"); Invalid cast. ... while without glibc debuginfo installed we get the expected result: ... $n = 0x7ffff7daa1b1 "aha" ... and likewise with glibc debuginfo generated with gas 2.40. The strstr ifunc resolves to __strstr_sse2_unaligned. The problem is that gas generates dwarf that states that the return type is void: ... <1><3e1e58>: Abbrev Number: 2 (DW_TAG_subprogram) <3e1e59> DW_AT_name : __strstr_sse2_unaligned <3e1e5d> DW_AT_external : 1 <3e1e5e> DW_AT_low_pc : 0xbbd2e <3e1e66> DW_AT_high_pc : 0xbc1c3 ... while the return type should be a DW_TAG_unspecified_type, as is the case with gas 2.40. We can still use the workaround of casting to another function type for both __strstr_sse2_unaligned: ... (gdb) p ((char * (*) (const char *, const char *))__strstr_sse2_unaligned) \ ("haha", "ah") $n = 0x7ffff7daa211 "aha" ... and strstr (which requires using *strstr to dereference the ifunc before we cast): ... gdb) p ((char * (*) (const char *, const char *))*strstr) ("haha", "ah") $n = 0x7ffff7daa251 "aha" ... but that's a bit cumbersome to use. Work around this in the dwarf reader, such that we have instead: ... (gdb) p (char *)strstr ("haha", "ah") $n = 0x7ffff7daa1b1 "aha" ... This also requires fixing producer_is_gcc to stop returning true for producer "GNU AS 2.39.0". Tested on x86_64-linux. Approved-By: Andrew Burgess <aburgess@redhat.com> PR symtab/30911 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30911
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5ce0e02478cc79a260c7e29822450284a32b9b12 commit 5ce0e02478cc79a260c7e29822450284a32b9b12 Author: Tom de Vries <tdevries@suse.de> Date: Thu May 2 09:34:46 2024 +0200 [gdb/symtab] Work around PR gas/29517, dwarf2 case In commit 1d45d90934b ("[gdb/symtab] Work around PR gas/29517") we added a workaround for PR gas/29517. The problem is present in gas version 2.39, and fixed in 2.40, so the workaround is only active for gas version == 2.39. However, the problem in gas is only fixed for dwarf version >= 3, which supports DW_TAG_unspecified_type. Fix this by also activating the workaround for dwarf version == 2. Tested on x86_64-linux. Approved-by: Kevin Buettner <kevinb@redhat.com> PR symtab/31689 https://sourceware.org/bugzilla/show_bug.cgi?id=31689