From: Mike Gulick <mgulick@mathworks.com>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Cc: Mike Gulick <mgulick@mathworks.com>
Subject: [RFC] Apply compilation dir to source_path lookup
Date: Thu, 05 Sep 2019 22:40:00 -0000 [thread overview]
Message-ID: <8058b501-9020-84f1-ecf4-b46bfe3b86e3@mathworks.com> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 5139 bytes --]
Hi,
I'm having trouble getting gdb to find the corresponding source for a
binary whose compilation directory was rewritten using
-fdebug-prefix-map. I am doing this in order to make builds
reproducible. I am using this gcc switch to remove a portion of the
compile directory, e.g.
$ cd $HOME/test/src/
$ gcc -g -o test -fdebug-prefix-map=$HOME= test.c
$ dwarfdump test
...
DW_AT_name test.c
DW_AT_comp_dir /test/src
...
When attempting to debug the resulting binary, gdb is unable to find the
source file even if I add the removed path $HOME to the gdb source
path:
$ cd $HOME
$ gdb --nh ~/test/src/test
GNU gdb (GDB) 8.3
...
(gdb) directory /home/mgulick
Source directories searched: /home/mgulick:$cdir:$cwd
(gdb) info sources
Source files for which symbols have been read in:
/test/src/test.c
Source files for which symbols will be read in on demand:
(gdb) b test.c:3
Breakpoint 1 at 0x664: file test.c, line 3.
(gdb) r
Starting program: /mathworks/home/mgulick/test/src/test
Breakpoint 1, main () at test.c:3
3 test.c: No such file or directory.
It turns out that only the source file, i.e. DW_AT_name, is used when
searching the source path. This is surprising given the example with
'/usr/src/foo-1.0/lib/foo.c' and '/mnt/cross' in the gdb documentation
here: https://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html. It
seems uncommon for DW_AT_name to be the full path to the source file in
most programs I have come across. In that example from the
documentation, it is likely that DW_AT_name would be 'lib/foo.c' and
DW_AT_comp_dir would be '/usr/src/foo-1.0'.
I have implemented two different approaches to handle this, both of
which work, and I wanted feedback on a) whether you think this is a
legitimate bug/feature, and b) which approach you prefer.
Approach 1 is to include another pass in find_and_open_source where the
compilation directory is prepended to the filename before searching for
the file with openp. This allows the example I provided above to work
as-is.
Approach 2 is to allow '$cdir' to appear as part of an entry in the
source_path. Currently it is only allowed to exist as a standalone
entry. This would allow me to say 'directory /home/mgulick/$cdir', and
find_and_open_source would expand the $cdir part of this string to the
compilation directory.
I prefer approach 1 for a couple of reasons:
1) It is simpler for users to understand. It doesn't really require
understanding the difference between DW_AT_comp_dir and DW_AT_name. It
will match the source file in /home/mgulick/test.c, /test/src/test.c, or
/home/mgulick/test/src/test.c. Of course, since '$cdir' is still in
source_path, it will also look in /test/src/test/src/test.c, which is a
little confusing, but shouldn't be a problem (and we could explicitly
remove '$cdir' from the path when doing this search).
2) It seems to match the existing gdb documentation.
I dislike approach 2 because it makes the directory strings more
complicated, and it also means I'm unable to have a directory named
'/home/mgulick/$cdir' (bizarre, I know, but such things are possible).
Here is a preliminary patch for the first approach. I will go ahead and
add a test-case and re-send a formal patch review request if this seems
like an acceptable solution.
Thanks,
Mike
diff --git a/gdb/source.c b/gdb/source.c
index b27f210802..b7b5741028 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1033,7 +1033,35 @@ find_and_open_source (const char *filename,
openp_flags flags = OPF_SEARCH_IN_PATH;
if (basenames_may_differ)
flags |= OPF_RETURN_REALPATH;
+
+ /* Try to locate file using filename */
result = openp (path, flags, filename, OPEN_MODE, fullname);
+ if (result < 0 && dirname != NULL)
+ {
+ /* Try to locate file using compilation dir + filename. This is helpful
+ if part of the compilation directory was removed, e.g. using gcc's
+ -fdebug-prefix-map, and we have added the missing prefix to
+ source_path. */
+ /* Allocate space for dirname, possibly an extra slash, the filename,
+ and terminating null */
+ char * cdir_filename = (char *)
+ alloca (strlen (dirname) + strlen(SLASH_STRING) + strlen (filename) + 1);
+
+ cdir_filename = strcpy (cdir_filename, dirname);
+ int len = strlen (cdir_filename); /* last char in cdir_filename */
+
+ /* Add directory separator if not provided by dirname or filename */
+ if (!(IS_DIR_SEPARATOR (cdir_filename[len]) ||
+ IS_DIR_SEPARATOR (filename[0])))
+ strcat (cdir_filename, SLASH_STRING);
+ else if (IS_DIR_SEPARATOR (cdir_filename[len]) &&
+ IS_DIR_SEPARATOR (filename[0]))
+ /* Both provide a slash, use only one */
+ cdir_filename[len] = '\0';
+ strcat(cdir_filename,filename);
+
+ result = openp(path, flags, cdir_filename, OPEN_MODE, fullname);
+ }
if (result < 0)
{
/* Didn't work. Try using just the basename. */
\x16º&Öéj×!zÊÞ¶êç×9÷yb²Ö«r\x18\x1dnr\x17¬
next reply other threads:[~2019-09-05 22:40 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-05 22:40 Mike Gulick [this message]
2019-09-07 23:51 ` Andrew Burgess
2019-09-09 22:41 ` Mike Gulick
2019-09-13 1:38 ` Andrew Burgess
2019-09-13 6:36 ` Eli Zaretskii
2019-09-13 7:28 ` Eli Zaretskii
2019-09-13 22:45 ` Andrew Burgess
2019-09-13 22:52 ` Mike Gulick
2019-09-14 7:11 ` Eli Zaretskii
2019-09-17 20:22 ` Andrew Burgess
2019-09-17 20:39 ` Mike Gulick
2019-09-14 6:56 ` Eli Zaretskii
2019-09-14 15:28 ` Andrew Burgess
2019-09-14 15:54 ` Eli Zaretskii
2019-09-15 2:07 ` Mike Gulick
2019-09-15 4:01 ` Andrew Burgess
2019-09-15 15:29 ` Eli Zaretskii
2019-09-16 15:53 ` Mike Gulick
2019-09-13 22:11 ` Mike Gulick
2019-09-13 22:41 ` Andrew Burgess
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=8058b501-9020-84f1-ecf4-b46bfe3b86e3@mathworks.com \
--to=mgulick@mathworks.com \
--cc=gdb-patches@sourceware.org \
/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