From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id C40B83857C4A for ; Thu, 7 Apr 2022 01:52:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C40B83857C4A X-ASG-Debug-ID: 1649296324-0c856e06adafae30001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id GWHGbrNRoZNBbDu5 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 06 Apr 2022 21:52:04 -0400 (EDT) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.localdomain (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) by smtp.ebox.ca (Postfix) with ESMTP id 6345F441D68; Wed, 6 Apr 2022 21:52:01 -0400 (EDT) From: Simon Marchi X-Barracuda-RBL-IP: 192.222.157.6 X-Barracuda-Effective-Source-IP: 192-222-157-6.qc.cable.ebox.net[192.222.157.6] X-Barracuda-Apparent-Source-IP: 192.222.157.6 To: gdb-patches@sourceware.org Subject: [PATCH 5/6] gdb: prepend comp_dir to symtab name in buildsym_compunit Date: Wed, 6 Apr 2022 21:51:58 -0400 X-ASG-Orig-Subj: [PATCH 5/6] gdb: prepend comp_dir to symtab name in buildsym_compunit Message-Id: <20220407015159.1734834-6-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220407015159.1734834-1-simon.marchi@polymtl.ca> References: <20220407015159.1734834-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1649296324 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 6793 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.97177 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3613.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_QUARANTINE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Apr 2022 01:52:18 -0000 Printing macros defined in the main source file doesn't work reliably using various toolchains, especially when DWARF 5 is used. For example, using either of these binaries: $ gcc --version gcc (GCC) 11.2.0 $ ld --version GNU ld (GNU Binutils) 2.38 $ gcc test.c -g3 -gdwarf-5 $ clang --version clang version 13.0.1 $ clang test.c -gdwarf-5 -fdebug-macro I get: $ ./gdb -nx -q --data-directory=data-directory a.out (gdb) start Temporary breakpoint 1 at 0x111d: file test.c, line 6. Starting program: /home/simark/build/binutils-gdb-one-target/gdb/a.out Temporary breakpoint 1, main () at test.c:6 6 return ZERO; (gdb) p ZERO No symbol "ZERO" in current context. When starting to investigate this (taking the gcc-compiled binary as an example), we see that GDB fails to look up the appropriate macro scope when evaluating the expression. While stopped in macro_lookup_inclusion: (top-gdb) p name $1 = 0x62100011a980 "test.c" (top-gdb) p source.filename $2 = 0x62100011a9a0 "/home/simark/build/binutils-gdb-one-target/gdb/test.c" `source` is the macro_source_file that we would expect GDB to find. But it doesn't find it because the filename it is looking for isn't exactly like the filename as written in the macro_source_file object. The `name` parameter comes from the symtab::filename field of the symtab we are stopped at. The symtab's filename comes from the compilation unit's DW_AT_name, passed to the buildsym_compunit's constructor: https://gitlab.com/gnutools/binutils-gdb/-/blob/4815d6125ec580cc02a1094d61b8c9d1cc83c0a1/gdb/dwarf2/read.c#L10627-10630 The name is used as is to create the main subfile of the compunit, which eventually becomes a symtab. In this case it is just the filename, "test.c". The name of the macro_source_file comes from the line number program header's file table, from the call to the line_header::file_file_name method: https://gitlab.com/gnutools/binutils-gdb/-/blob/4815d6125ec580cc02a1094d61b8c9d1cc83c0a1/gdb/dwarf2/macro.c#L54-65 line_header::file_file_name prepends the directory path the file is relative to, if the file name is not absolute. In this case, the file name is "test.c", appended to the directory "/home/simark/build/binutils-gdb-one-target/gdb". Because the symtab's name is not created the same way as the macro_source_file's name is created, we get this mismatch. This patch fixes things locally in a rather naive way by making buildsym_compunit format the main subfile's name the same way as the DWARF reader formats the main name, that is by prepending the directory part. Since this changes some symtab names, there is some user-visible changes when those names are output, as can be seen from the few tests I needed to update. The difference is that some symtab names that previously didn't include a directory portion will now include one. Finally, change the comment above the line_header::file_file_name declaration. The part about it returning a name relative the compilation directory is just not true, it thought it was very misleading. There isn't much we can guarantee about how the returned file name will look like, because it depends on what the compiler decided to put in the file and directory tables. Change-Id: I0372906dafc01d6b3774b2ab72f9d28d7069b6cc --- gdb/buildsym.c | 15 +++++++++++++++ gdb/dwarf2/line-header.h | 5 +---- gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp | 2 +- gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 4718b201f036..c1c588a869dc 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -71,6 +71,21 @@ buildsym_compunit::buildsym_compunit (struct objfile *objfile_, non-primary symtabs. It is also needed by get_macro_table. */ m_compunit_symtab = allocate_compunit_symtab (m_objfile, name); + std::string name_copy; + + /* In order not to lose the line information directory, + we concatenate it to the filename when it makes sense. + Note that the Dwarf3 standard says (speaking of filenames in line + information): ``The directory index is ignored for file names + that represent full path names''. Thus ignoring dirname in the + `else' branch below isn't an issue. */ + + if (!IS_ABSOLUTE_PATH (name) && m_comp_dir != nullptr) + { + name_copy = string_printf ("%s/%s", m_comp_dir.get (), name); + name = name_copy.c_str (); + } + /* Build the subfile for NAME (the main source file) so that we can record a pointer to it for later. IMPORTANT: Do not allocate a struct symtab for NAME here. diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index 8fb44be56b2e..845fbebfa8d3 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -162,10 +162,7 @@ struct line_header header. These point into dwarf2_per_objfile->line_buffer. */ const gdb_byte *statement_program_start {}, *statement_program_end {}; - /* Return file name relative to the compilation directory of file - number I in this object's file name table. The result is - allocated using xmalloc; the caller is responsible for freeing - it. */ + /* Return file name of file number FILE in this object's file name table. */ gdb::unique_xmalloc_ptr file_file_name (int file) const; private: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp index 2257dd228191..6ea68e1f997f 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp @@ -45,4 +45,4 @@ gdb_breakpoint "*outer_before" # FAIL was: # No line number information available for address 0x4 -gdb_test "info line inner" {Line 2 of "inner\.c" starts at address .*} +gdb_test "info line inner" {Line 2 of "/tmp/inner\.c" starts at address .*} diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl index fe92c530888d..d2a74c5031b1 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl +++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl @@ -126,4 +126,4 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ gdb_reinitialize_dir /tmp # Using an absolute path is important to see the bug. -gdb_test "break /tmp/${srcfile}:19" "Breakpoint .* file $srcfile, line .*" +gdb_test "break /tmp/${srcfile}:19" "Breakpoint .* file /tmp/$srcfile, line .*" -- 2.35.1