Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
selftests/bpf: Fix backtrace printing for selftests crashes
Browse files Browse the repository at this point in the history
[ Upstream commit 5bf1557 ]

test_progs uses glibc specific functions backtrace() and
backtrace_symbols_fd() to print backtrace in case of SIGSEGV.

Recent commit (see fixes) updated test_progs.c to define stub versions
of the same functions with attriubte "weak" in order to allow linking
test_progs against musl libc. Unfortunately this broke the backtrace
handling for glibc builds.

As it turns out, glibc defines backtrace() and backtrace_symbols_fd()
as weak:

  $ llvm-readelf --symbols /lib64/libc.so.6 \
     | grep -P '( backtrace_symbols_fd| backtrace)$'
  4910: 0000000000126b40   161 FUNC    WEAK   DEFAULT    16 backtrace
  6843: 0000000000126f90   852 FUNC    WEAK   DEFAULT    16 backtrace_symbols_fd

So does test_progs:

 $ llvm-readelf --symbols test_progs \
    | grep -P '( backtrace_symbols_fd| backtrace)$'
  2891: 00000000006ad190    15 FUNC    WEAK   DEFAULT    13 backtrace
 11215: 00000000006ad1a0    41 FUNC    WEAK   DEFAULT    13 backtrace_symbols_fd

In such situation dynamic linker is not obliged to favour glibc
implementation over the one defined in test_progs.

Compiling with the following simple modification to test_progs.c
demonstrates the issue:

  $ git diff
  ...
  \--- a/tools/testing/selftests/bpf/test_progs.c
  \+++ b/tools/testing/selftests/bpf/test_progs.c
  \@@ -1817,6 +1817,7 @@ int main(int argc, char **argv)
          if (err)
                  return err;

  +       *(int *)0xdeadbeef  = 42;
          err = cd_flavor_subdir(argv[0]);
          if (err)
                  return err;

  $ ./test_progs
  [0]: Caught signal torvalds#11!
  Stack trace:
  <backtrace not supported>
  Segmentation fault (core dumped)

Resolve this by hiding stub definitions behind __GLIBC__ macro check
instead of using "weak" attribute.

Fixes: c9a83e7 ("selftests/bpf: Fix compile if backtrace support missing in libc")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Tested-by: Tony Ambardar <tony.ambardar@gmail.com>
Reviewed-by: Tony Ambardar <tony.ambardar@gmail.com>
Acked-by: Daniel Xu <dxu@dxuuu.xyz>
Link: https://lore.kernel.org/bpf/20241003210307.3847907-1-eddyz87@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
eddyz87 authored and gregkh committed Dec 2, 2024
1 parent ded165d commit 98d7b9f
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions tools/testing/selftests/bpf/test_progs.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
#include <sys/socket.h>
#include <sys/un.h>

/* backtrace() and backtrace_symbols_fd() are glibc specific,
* use header file when glibc is available and provide stub
* implementations when another libc implementation is used.
*/
#ifdef __GLIBC__
#include <execinfo.h> /* backtrace */
#endif

/* Default backtrace funcs if missing at link */
#else
__weak int backtrace(void **buffer, int size)
{
return 0;
Expand All @@ -30,6 +32,7 @@ __weak void backtrace_symbols_fd(void *const *buffer, int size, int fd)
{
dprintf(fd, "<backtrace not supported>\n");
}
#endif /*__GLIBC__ */

static bool verbose(void)
{
Expand Down

0 comments on commit 98d7b9f

Please sign in to comment.