libbacktrace
libbacktrace copied to clipboard
backtrace returns mix of absolute and relative paths; how to force absolute paths?
after investigation, this is the root cause for https://github.com/status-im/nim-libbacktrace/issues/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
https://github.com/ianlancetaylor/libbacktrace/issues/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);