Skip to content

Commit

Permalink
[PATCH] fix symbol search loop at debuglink mode
Browse files Browse the repository at this point in the history
Some distribs like ubuntu'18 creatively name files with debug symbols.
(same name without .debug suffix). And give no `build-id` way.

$dpkg -L libc6-dbg | grep -v gconv
/usr/lib/debug/.build-id/68/f36706eb2e6eee4046c4fdca2a19540b2f6113.debug
/usr/lib/debug/lib/x86_64-linux-gnu/libc-2.27.so

$ dpkg -L libc6
/lib/x86_64-linux-gnu/libc-2.27.so
/lib/x86_64-linux-gnu/libc.so.6

$ objdump -s -j .gnu_debuglink -j .note.gnu.build-id \
  /lib/x86_64-linux-gnu/libc-2.27.so

Contents of section .gnu_debuglink:
 0000 6c696263 2d322e32 372e736f 00000000  libc-2.27.so....
 0010 5ac51387                             Z...
Contents of section .note.gnu.build-id:
 0270 04000000 14000000 03000000 474e5500  ............GNU.
 0280 ce450eb0 1a5e5acc 7ce7b8c2 633b02cc  .E...^Z.|...c;..
 0290 1093339e                             ..3.

So elf_find_debugfile_by_debuglink("libc") loops back to
/lib/x86_64-linux-gnu/libc-2.27.so and can't lookup symbols for libc and
another standard libs. This patch breaks this loop and allows to lookup
for symbols at other places.
  • Loading branch information
pavel-orekhov committed Mar 3, 2021
1 parent 4f57c99 commit 7c8f080
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ static int
elf_try_debugfile (struct backtrace_state *state, const char *prefix,
size_t prefix_len, const char *prefix2, size_t prefix2_len,
const char *debuglink_name,
const char *ref_filename,
backtrace_error_callback error_callback, void *data)
{
size_t debuglink_len;
Expand All @@ -936,6 +937,9 @@ elf_try_debugfile (struct backtrace_state *state, const char *prefix,
memcpy (try + prefix_len + prefix2_len, debuglink_name, debuglink_len);
try[prefix_len + prefix2_len + debuglink_len] = '\0';

if(ref_filename && *ref_filename && !strcmp(try, ref_filename))
return -1; // loop detected

ret = backtrace_open (try, error_callback, data, &does_not_exist);

backtrace_free (state, try, try_len, error_callback, data);
Expand Down Expand Up @@ -1026,7 +1030,8 @@ elf_find_debugfile_by_debuglink (struct backtrace_state *state,
}

ddescriptor = elf_try_debugfile (state, prefix, prefix_len, "", 0,
debuglink_name, error_callback, data);
debuglink_name, filename,
error_callback, data);
if (ddescriptor >= 0)
{
ret = ddescriptor;
Expand All @@ -1037,7 +1042,7 @@ elf_find_debugfile_by_debuglink (struct backtrace_state *state,

ddescriptor = elf_try_debugfile (state, prefix, prefix_len, ".debug/",
strlen (".debug/"), debuglink_name,
error_callback, data);
filename, error_callback, data);
if (ddescriptor >= 0)
{
ret = ddescriptor;
Expand All @@ -1049,7 +1054,7 @@ elf_find_debugfile_by_debuglink (struct backtrace_state *state,
ddescriptor = elf_try_debugfile (state, "/usr/lib/debug/",
strlen ("/usr/lib/debug/"), prefix,
prefix_len, debuglink_name,
error_callback, data);
filename, error_callback, data);
if (ddescriptor >= 0)
ret = ddescriptor;

Expand Down

0 comments on commit 7c8f080

Please sign in to comment.