From: Sergio Durigan Junior via Gdb-patches <gdb-patches@sourceware.org>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simark@simark.ca>, Mark Wielaard <mark@klomp.org>,
Sergio Durigan Junior <sergiodj@sergiodj.net>
Subject: [PATCH v2] Search for DWZ files in debug-file-directories as well
Date: Wed, 18 Nov 2020 21:27:08 -0500 [thread overview]
Message-ID: <20201119022708.3627287-1-sergiodj@sergiodj.net> (raw)
In-Reply-To: <20201114234842.2334396-1-sergiodj@sergiodj.net>
Changes from v1:
- Addressed Simon's comments (new comment explaining how we try to
match for the current debug-file-directory; properly use
.erase/.insert methods -- keeping in mind that they modify the
string in-place).
When Debian (and Ubuntu) builds its binaries, it (still) doesn't use
dwz's "--relative" option. This causes their debuginfo files to
carry a .gnu_debugaltlink section containing a full pathname to the
DWZ alt debug file, like this:
$ readelf -wk /usr/bin/cat
Contents of the .gnu_debugaltlink section:
Separate debug info file: /usr/lib/debug/.dwz/x86_64-linux-gnu/coreutils.debug
Build-ID (0x14 bytes):
ee 76 5d 71 97 37 ce 46 99 44 32 bb e8 a9 1a ef 99 96 88 db
Contents of the .gnu_debuglink section:
Separate debug info file: 06d3bee37b8c7e67b31cb2689cb351102ae73b.debug
CRC value: 0x53267655
This usually works OK, because most of the debuginfo files installed
via apt will be present in /usr/lib/debug anyway. However, imagine
the following scenario:
- You are using /usr/bin/cat, it crashes on you and generates a
corefile.
- You don't want/need to "apt install" the debuginfo file for
coreutils from the repositories. Instead, you already have the
debuginfo files in a separate directory (e.g., $HOME/dbgsym).
- You start GDB and "set debug-file-directory $HOME/dbgsym".
You then get the following message:
$ gdb -ex 'set debug-file-directory ./dbgsym/usr/lib/debug' -ex 'file /bin/cat' -ex 'core-file ./cat.core'
GNU gdb (Ubuntu 10.1-0ubuntu1) 10.1
...
Reading symbols from /bin/cat...
Reading symbols from /home/sergio/gdb/dbgsym/usr/lib/debug/.build-id/bc/06d3bee37b8c7e67b31cb2689cb351102ae73b.debug...
could not find '.gnu_debugaltlink' file for /home/sergio/gdb/dbgsym/usr/lib/debug/.build-id/bc/06d3bee37b8c7e67b31cb2689cb351102ae73b.debug
This error happens because GDB is trying to locate the build-id
link (inside /home/sergio/gdb/dbgsym/usr/lib/debug/.build-id) for the
DWZ alt debug file, which doesn't exist. Arguably, this is a problem
with how dh_dwz works in Debian, and it's something I'm also planning
to tackle. But, back at the problem at hand.
Besides not being able to find the build-id link in the directory
mentioned above, GDB also tried to open the DWZ alt file using its
filename. The problem here is that, since we don't have the distro's
debuginfo installed, it can't find anything under /usr/lib/debug that
satisfies it.
It occurred to me that a good way to workaround this problem is to
actually try to locate the DWZ alt debug file inside the
debug-file-directories (that were likely provided by the user). So
this is what the proposed patch does.
The idea here is simple: get the filename extracted from the
.gnu_debugaltlink section, and manipulate it in order to replace the
initial part of the path (everything before "/.dwz/") by whatever
debug-file-directories the user might have provided.
I talked with Mark Wielaard and he agrees this is a sensible approach.
In fact, apparently this is something that eu-readelf also does.
I regtested this code, and no regressions were found.
2020-11-14 Sergio Durigan Junior <sergiodj@sergiodj.net>
* dwarf2/read.c (dwarf2_get_dwz_file): Convert 'filename' to a
std::string. Implement ability to search for DWZ files in the
debug-file-directories provided by the user as well.
---
gdb/dwarf2/read.c | 73 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 67 insertions(+), 6 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3c59826291..c462b9bb2c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2190,7 +2190,7 @@ locate_dwz_sections (bfd *abfd, asection *sectp, dwz_file *dwz_file)
struct dwz_file *
dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
{
- const char *filename;
+ std::string filename;
bfd_size_type buildid_len_arg;
size_t buildid_len;
bfd_byte *buildid;
@@ -2216,19 +2216,17 @@ dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
filename = data.get ();
- std::string abs_storage;
- if (!IS_ABSOLUTE_PATH (filename))
+ if (!IS_ABSOLUTE_PATH (filename.c_str ()))
{
gdb::unique_xmalloc_ptr<char> abs
= gdb_realpath (bfd_get_filename (per_bfd->obfd));
- abs_storage = ldirname (abs.get ()) + SLASH_STRING + filename;
- filename = abs_storage.c_str ();
+ filename = ldirname (abs.get ()) + SLASH_STRING + filename;
}
/* First try the file name given in the section. If that doesn't
work, try to use the build-id instead. */
- gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget));
+ gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename.c_str (), gnutarget));
if (dwz_bfd != NULL)
{
if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
@@ -2238,6 +2236,69 @@ dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
if (dwz_bfd == NULL)
dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
+ if (dwz_bfd == nullptr)
+ {
+ /* If the user has provided us with different
+ debug-file-directories, we can try them in order. */
+ size_t dwz_pos = filename.find ("/.dwz/");
+
+ if (dwz_pos != std::string::npos)
+ {
+ std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
+ = dirnames_to_char_ptr_vec (debug_file_directory);
+
+ for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
+ {
+ /* The idea is to iterate over the
+ debug-file-directories provided by the user and
+ replace the hard-coded path in the "filename" by each
+ debug-file-directory.
+
+ For example, suppose that filename is:
+
+ /usr/lib/debug/.dwz/foo.dwz
+
+ And suppose that we have "$HOME/bar" as the
+ debug-file-directory. We would then adjust filename
+ to look like:
+
+ $HOME/bar/.dwz/foo.dwz
+
+ which would hopefully allow us to find the alt debug
+ file. */
+ std::string ddir = debugdir.get ();
+
+ /* Check whether the beginning of FILENAME is DDIR. If
+ it is, then we are dealing with a file which we
+ already attempted to open before, so we just skip it
+ and continue processing the reamining
+ debug-file-directories. */
+ if (filename.size () > ddir.size ()
+ && filename.compare (0, ddir.size (), ddir) == 0)
+ continue;
+
+ /* Replace FILENAME's default debug-file-directory with
+ DDIR. */
+ std::string new_filename = filename;
+ new_filename.erase (0, dwz_pos);
+ new_filename.insert (0, ddir);
+
+ dwz_bfd = gdb_bfd_open (new_filename.c_str (), gnutarget);
+
+ if (dwz_bfd != nullptr)
+ {
+ if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+ {
+ dwz_bfd.reset (nullptr);
+ continue;
+ }
+ /* Found it. */
+ break;
+ }
+ }
+ }
+ }
+
if (dwz_bfd == nullptr)
{
gdb::unique_xmalloc_ptr<char> alt_filename;
--
2.28.0
next prev parent reply other threads:[~2020-11-19 2:27 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-14 23:48 [PATCH] " Sergio Durigan Junior via Gdb-patches
2020-11-15 13:19 ` Mark Wielaard
2020-11-16 1:25 ` Simon Marchi
2020-11-16 9:32 ` Mark Wielaard
2020-11-16 17:57 ` Sergio Durigan Junior via Gdb-patches
2020-11-19 2:27 ` Sergio Durigan Junior via Gdb-patches [this message]
2020-11-25 15:09 ` [PATCH v2] " Sergio Durigan Junior via Gdb-patches
2020-11-25 16:58 ` Luis Machado via Gdb-patches
2020-11-28 20:51 ` Sergio Durigan Junior via Gdb-patches
2020-11-26 16:53 ` Simon Marchi
2020-11-28 20:58 ` Sergio Durigan Junior via Gdb-patches
2020-11-28 21:35 ` Sergio Durigan Junior via Gdb-patches
2020-11-28 22:13 ` Simon Marchi
2020-11-28 22:12 ` Simon Marchi
2020-11-29 0:57 ` Sergio Durigan Junior via Gdb-patches
2020-11-29 1:29 ` Simon Marchi
2020-11-29 1:08 ` [PATCH v3] " Sergio Durigan Junior via Gdb-patches
2020-12-01 14:45 ` Simon Marchi
2020-12-02 3:08 ` Sergio Durigan Junior via Gdb-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201119022708.3627287-1-sergiodj@sergiodj.net \
--to=gdb-patches@sourceware.org \
--cc=mark@klomp.org \
--cc=sergiodj@sergiodj.net \
--cc=simark@simark.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox