diff mbox series

[bpf] selftests/bpf: fix backtrace printing for selftests crashes

Message ID 20241003210307.3847907-1-eddyz87@gmail.com (mailing list archive)
State Accepted
Commit 5bf1557e3d6a69113649d831276ea2f97585fc33
Delegated to: BPF
Headers show
Series [bpf] selftests/bpf: fix backtrace printing for selftests crashes | expand

Checks

Context Check Description
bpf/vmtest-bpf-PR success PR summary
bpf/vmtest-bpf-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-22 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-29 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-VM_Test-36 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-12 success Logs for s390x-gcc / build-release
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 14 maintainers not CCed: mykolal@fb.com sdf@fomichev.me llvm@lists.linux.dev haoluo@google.com shuah@kernel.org jolsa@kernel.org ndesaulniers@google.com nathan@kernel.org linux-kselftest@vger.kernel.org justinstitt@google.com song@kernel.org morbo@google.com kpsingh@kernel.org john.fastabend@gmail.com
netdev/build_clang success Errors and warnings before: 7 this patch: 7
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes fail Problems with Fixes tag: 1
netdev/build_allmodconfig_warn success Errors and warnings before: 7 this patch: 7
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 28 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-VM_Test-7 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-VM_Test-10 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-VM_Test-3 success Logs for Validate matrix.py

Commit Message

Eduard Zingerman Oct. 3, 2024, 9:03 p.m. UTC
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 #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: c9a83e76b5a9 ("selftests/bpf: Fix compile if backtrace support missing in libc")

CC: Tony Ambardar <tony.ambardar@gmail.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 tools/testing/selftests/bpf/test_progs.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

Comments

Eduard Zingerman Oct. 3, 2024, 9:07 p.m. UTC | #1
On Thu, 2024-10-03 at 14:03 -0700, Eduard Zingerman wrote:

[...]

> Resolve this by hiding stub definitions behind __GLIBC__ macro check
> instead of using "weak" attribute.
> 
> Fixes: c9a83e76b5a9 ("selftests/bpf: Fix compile if backtrace support missing in libc")

Hi Tony,

could you please double-check if your musl setup behaves as expected
after these changes?

Thanks,
Eduard
Daniel Xu Oct. 4, 2024, 5:21 p.m. UTC | #2
On Thu, Oct 03, 2024 at 02:03:07PM GMT, Eduard Zingerman wrote:
> 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 #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: c9a83e76b5a9 ("selftests/bpf: Fix compile if backtrace support missing in libc")
> 
> CC: Tony Ambardar <tony.ambardar@gmail.com>
> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> ---
>  tools/testing/selftests/bpf/test_progs.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
> index 7846f7f98908..005ff506b527 100644
> --- a/tools/testing/selftests/bpf/test_progs.c
> +++ b/tools/testing/selftests/bpf/test_progs.c
> @@ -20,20 +20,23 @@
>  
>  #include "network_helpers.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 */
> -__weak int backtrace(void **buffer, int size)
> +#else
> +int backtrace(void **buffer, int size)
>  {
>  	return 0;
>  }
>  
> -__weak void backtrace_symbols_fd(void *const *buffer, int size, int fd)
> +void backtrace_symbols_fd(void *const *buffer, int size, int fd)
>  {
>  	dprintf(fd, "<backtrace not supported>\n");
>  }
> +#endif /*__GLIBC__ */
>  
>  int env_verbosity = 0;
>  
> -- 
> 2.46.1
> 
> 

Acked-by: Daniel Xu <dxu@dxuuu.xyz>
Tony Ambardar Oct. 6, 2024, 8:12 a.m. UTC | #3
On Thu, Oct 03, 2024 at 02:07:23PM -0700, Eduard Zingerman wrote:
> On Thu, 2024-10-03 at 14:03 -0700, Eduard Zingerman wrote:
> 
> [...]
> 
> > Resolve this by hiding stub definitions behind __GLIBC__ macro check
> > instead of using "weak" attribute.
> > 
> > Fixes: c9a83e76b5a9 ("selftests/bpf: Fix compile if backtrace support missing in libc")
> 
> Hi Tony,
> 
> could you please double-check if your musl setup behaves as expected
> after these changes?
> 

Hi Eduard,

I discovered building for musl has broken over the last month or so, and
it took some time to find fixes and workarounds before I could retest.

Since glibc execinfo.h also defines its functions as weak, and given the
linking issues that can cause, I think changing the #ifdef as you did is
the right approach. But could you leave the fallback stub functions as
"__weak" like before to simplify overriding in the non-GLIBC case?

Otherwise:

Reviewed-by: Tony Ambardar <tony.ambardar@gmail.com>
Tested-by: Tony Ambardar <tony.ambardar@gmail.com>

Thanks,
Tony

> Thanks,
> Eduard
>
Andrii Nakryiko Oct. 8, 2024, 3:39 a.m. UTC | #4
On Sun, Oct 6, 2024 at 1:12 AM Tony Ambardar <tony.ambardar@gmail.com> wrote:
>
> On Thu, Oct 03, 2024 at 02:07:23PM -0700, Eduard Zingerman wrote:
> > On Thu, 2024-10-03 at 14:03 -0700, Eduard Zingerman wrote:
> >
> > [...]
> >
> > > Resolve this by hiding stub definitions behind __GLIBC__ macro check
> > > instead of using "weak" attribute.
> > >
> > > Fixes: c9a83e76b5a9 ("selftests/bpf: Fix compile if backtrace support missing in libc")
> >
> > Hi Tony,
> >
> > could you please double-check if your musl setup behaves as expected
> > after these changes?
> >
>
> Hi Eduard,
>
> I discovered building for musl has broken over the last month or so, and
> it took some time to find fixes and workarounds before I could retest.
>
> Since glibc execinfo.h also defines its functions as weak, and given the
> linking issues that can cause, I think changing the #ifdef as you did is
> the right approach. But could you leave the fallback stub functions as
> "__weak" like before to simplify overriding in the non-GLIBC case?
>

I added __weak back while applying.

> Otherwise:
>
> Reviewed-by: Tony Ambardar <tony.ambardar@gmail.com>
> Tested-by: Tony Ambardar <tony.ambardar@gmail.com>
>
> Thanks,
> Tony
>
> > Thanks,
> > Eduard
> >
patchwork-bot+netdevbpf@kernel.org Oct. 8, 2024, 3:40 a.m. UTC | #5
Hello:

This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:

On Thu,  3 Oct 2024 14:03:07 -0700 you wrote:
> 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.
> 
> [...]

Here is the summary with links:
  - [bpf] selftests/bpf: fix backtrace printing for selftests crashes
    https://git.kernel.org/bpf/bpf-next/c/5bf1557e3d6a

You are awesome, thank you!
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 7846f7f98908..005ff506b527 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -20,20 +20,23 @@ 
 
 #include "network_helpers.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 */
-__weak int backtrace(void **buffer, int size)
+#else
+int backtrace(void **buffer, int size)
 {
 	return 0;
 }
 
-__weak void backtrace_symbols_fd(void *const *buffer, int size, int fd)
+void backtrace_symbols_fd(void *const *buffer, int size, int fd)
 {
 	dprintf(fd, "<backtrace not supported>\n");
 }
+#endif /*__GLIBC__ */
 
 int env_verbosity = 0;