Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backtrace returns mix of absolute and relative paths; how to force absolute paths? #72

Open
timotheecour opened this issue Apr 6, 2021 · 0 comments

Comments

@timotheecour
Copy link

timotheecour commented Apr 6, 2021

after investigation, this is the root cause for status-im/nim-libbacktrace#11

this library does not preserve absolute paths in backtrace if the input file is rooted under $PWD/anydir/

it does preserve absolute paths if the input file is under $PWD/foo.c or not rooted under $PWD (eg /other/foo.c)

this is a problem for several reasons eg

  • when a script changes directory and then invokes compilation
  • when different files are compiled in different directories
  • when users expect absolute paths

note that in all cases, I'm invoking clang with absolute paths (and dwarfdump correctly shows absolute paths)

to reproduce

git clone https://github.com/ianlancetaylor/libbacktrace
cd libbacktrace
./configure
apply the patch [1] which simply adds a call to backtrace_print
mkdir sub
cp mtest.c sub # note that, as noted above, things work if we use $(pwd)/mtest.c, but not $(pwd)/sub/mtest.c
DESTDIR=/tmp/d15c make install

  • clang -o /tmp/z01 -L/tmp/d15c/usr/local/lib -g -I. $(pwd)/sub/mtest.c testlib.c -Wl,-lbacktrace
  • /tmp/z01

output

D20210405T202237
0x103c24de8 f3
sub/mtest.c:112
0x103c24d17 f2
sub/mtest.c:94
0x103c24ccd test1
sub/mtest.c:88
0x103c24c8e main
sub/mtest.c:404
PASS: backtrace_full noinline
PASS: backtrace_simple noinline
test5: unexpected syminfo name got _dyld_private expected global
FAIL: backtrace_syminfo variable

expected output

$PWD/sub/mtest.c instead of sub/mtest.c, where $PWD is the current dir

maybe related

#26

patch [1]

diff --git a/mtest.c b/mtest.c
index 7e0189a..f3a682b 100644
--- a/mtest.c
+++ b/mtest.c
@@ -108,6 +108,8 @@ f3 (int f1line __attribute__ ((unused)), int f2line __attribute__ ((unused)))
   data.failed = 0;

   i = backtrace_full (state, 0, callback_mtest, error_callback_one, &data);
+  printf("D20210405T202237\n");
+  backtrace_print (state, 0, stdout);

   if (i != 0)
     {

note 1

i'm on osx, if that matters

note 2

after investigating, in dwarf.c:

  hdr->filenames[0] = u->filename;
  printf("D20210405T183857.2 %s\n", u->filename); // would print absolute paths

  i = 1;
  while (*hdr_buf->buf != '\0')
    {
      printf("ok1\n");
      const char *filename;
      uint64_t dir_index;

      if (hdr_buf->reported_underflow)
	return 0;

      filename = read_string (hdr_buf);
      printf("D20210405T183857.3 %s\n", filename); // would not print absolute paths
      if (filename == NULL)
	return 0;
      dir_index = read_uleb128 (hdr_buf);

note 3

DW_AT_comp_dir is probably incorrectly used (see comp_dir)
even if internal DWARF representation uses relative paths relative to compilation dir for compression, backtrace API should "decompress" those into absolute paths in a given compilation unit, at very least as an option.

The caller of backtrace API doesn't have access to DW_AT_comp_dir, in particular different compilation units could have their own DW_AT_comp_dir.

ntoe 4

the code in read_v2_paths seems relevant, eg:

	  memcpy (s + dir_len + 1, filename, filename_len + 1);

misc links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant