[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
abort-debug: Prefer libbacktrace to execinfo
From: |
Bruno Haible |
Subject: |
abort-debug: Prefer libbacktrace to execinfo |
Date: |
Sun, 19 May 2024 16:06:09 +0200 |
The stack traces that I get on the CI machines are not always useful,
in particular because no line number information is included.
With this patch, the abort-debug module uses the libbacktrace instead
of the execinfo facility. The output (on a Debian-based system) before:
../../gltests/test-floor1.c:36: assertion 'floor (0.0) == 3.0' failed
Stack trace:
./test-floor1(rpl_abort+0x3d) [0x559ead41c3ad]
./test-floor1(+0x1189) [0x559ead41c189]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f2378198d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f2378198e40]
./test-floor1(_start+0x25) [0x559ead41c1b5]
Aborted (core dumped)
and after the patch:
../../gltests/test-floor1.c:36: assertion 'floor (0.0) == 3.0' failed
Stack trace:
0x557a64e9c5f0 print_stack_trace
../../gllib/abort-debug.c:40
0x557a64e9c5f0 rpl_abort
../../gllib/abort-debug.c:94
0x557a64e9c458 main
../../gltests/test-floor1.c:36
0x7f496331bd8f __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
0x7f496331be3f __libc_start_main_impl
../csu/libc-start.c:392
0x557a64e9c484 ???
???:0
0xffffffffffffffff ???
???:0
Aborted (core dumped)
The lines
0x557a64e9c458 main
../../gltests/test-floor1.c:36
are definitely more informative than
./test-floor1(+0x1189) [0x559ead41c189]
2024-05-18 Bruno Haible <bruno@clisp.org>
abort-debug: Prefer libbacktrace to execinfo.
* lib/abort-debug.c: Include <backtrace.h>.
(state): New variable.
(print_stack_trace): Add another implementation.
(_gl_pre_abort, rpl_abort): Also test HAVE_LIBBACKTRACE.
* m4/abort-debug.m4 (gl_ABORT_DEBUG_EARLY): Check for libbacktrace.
Set LIBS, not LDFLAGS.
diff --git a/lib/abort-debug.c b/lib/abort-debug.c
index ca4dbc7291..8252b66def 100644
--- a/lib/abort-debug.c
+++ b/lib/abort-debug.c
@@ -21,7 +21,26 @@
#include <signal.h>
-#if HAVE_EXECINFO_H
+#if HAVE_LIBBACKTRACE
+
+# include <backtrace.h>
+
+static struct backtrace_state *state /* = NULL */;
+
+static inline void
+# if (__GNUC__ >= 3) || (__clang_major__ >= 4)
+__attribute__ ((always_inline))
+# endif
+print_stack_trace (FILE *stream)
+{
+ if (state == NULL)
+ state = backtrace_create_state (NULL, 0, NULL, NULL);
+ /* Pass skip=0, to work around
<https://github.com/ianlancetaylor/libbacktrace/issues/60>. */
+ fprintf (stream, "Stack trace:\n");
+ backtrace_print (state, 0, stream);
+}
+
+#elif HAVE_EXECINFO_H
# include <stdio.h>
@@ -58,7 +77,7 @@ print_stack_trace (FILE *stream)
void
_gl_pre_abort (void)
{
-#if HAVE_EXECINFO_H
+#if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H
print_stack_trace (stderr);
#endif
}
@@ -71,7 +90,7 @@ _gl_pre_abort (void)
void
rpl_abort (void)
{
-#if HAVE_EXECINFO_H
+#if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H
print_stack_trace (stderr);
#endif
raise (SIGABRT);
diff --git a/m4/abort-debug.m4 b/m4/abort-debug.m4
index e819d58dcb..61716e5a06 100644
--- a/m4/abort-debug.m4
+++ b/m4/abort-debug.m4
@@ -1,5 +1,5 @@
# abort-debug.m4
-# serial 1
+# serial 2
dnl Copyright (C) 2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -23,26 +23,55 @@ AC_DEFUN([gl_ABORT_DEBUG_EARLY]
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
if test $enable_debug_abort = yes; then
- AC_REQUIRE([AC_CANONICAL_HOST])
- case "$host_os" in
- *-gnu* | gnu* | darwin* | freebsd* | dragonfly* | netbsd* | openbsd* |
solaris*)
- dnl execinfo might be implemented on this platform.
- REPLACE_ABORT=1
- dnl On *BSD system, link all programs with -lexecinfo. Cf.
m4/execinfo.m4.
- case "$host_os" in
- freebsd* | dragonfly* | netbsd* | openbsd*)
- LDFLAGS="$LDFLAGS -lexecinfo"
- ;;
- esac
- dnl Link all programs in such a way that the stack trace includes the
- dnl function names. '-rdynamic' is equivalent to '-Wl,-export-dynamic'.
- case "$host_os" in
- *-gnu* | gnu* | openbsd*)
- LDFLAGS="$LDFLAGS -rdynamic"
- ;;
- esac
- ;;
- esac
+ dnl The first choice is libbacktrace by Ian Lance Taylor.
+ dnl Maintained at https://github.com/ianlancetaylor/libbacktrace,
+ dnl mirrored into GCC, installed as part of GCC by a few distros.
+ dnl It produces source file names and line numbers, if the binary
+ dnl is compiled with debug information.
+ AC_CACHE_CHECK([for libbacktrace], [gl_cv_lib_backtrace], [
+ gl_saved_LIBS="$LIBS"
+ LIBS="$gl_saved_LIBS -lbacktrace"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <backtrace.h>
+ ]],
+ [[struct backtrace_state *state =
+ backtrace_create_state (NULL, 0, NULL, NULL);
+ ]])],
+ [gl_cv_lib_backtrace=yes],
+ [gl_cv_lib_backtrace=no])
+ LIBS="$gl_saved_LIBS"
+ ])
+ if test $gl_cv_lib_backtrace = yes; then
+ AC_DEFINE([HAVE_LIBBACKTRACE], [1],
+ [Define if you have the libbacktrace library.])
+ REPLACE_ABORT=1
+ LIBS="$LIBS -lbacktrace"
+ else
+ dnl The second choice is libexecinfo.
+ dnl It does not produce source file names and line numbers, only
addresses
+ dnl (which are mostly useless due to ASLR) and _sometimes_ function
names.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ case "$host_os" in
+ *-gnu* | gnu* | darwin* | freebsd* | dragonfly* | netbsd* | openbsd* |
solaris*)
+ dnl execinfo might be implemented on this platform.
+ REPLACE_ABORT=1
+ dnl On *BSD system, link all programs with -lexecinfo. Cf.
m4/execinfo.m4.
+ case "$host_os" in
+ freebsd* | dragonfly* | netbsd* | openbsd*)
+ LIBS="$LIBS -lexecinfo"
+ ;;
+ esac
+ dnl Link all programs in such a way that the stack trace includes the
+ dnl function names. '-rdynamic' is equivalent to
'-Wl,-export-dynamic'.
+ case "$host_os" in
+ *-gnu* | gnu* | openbsd*)
+ LDFLAGS="$LDFLAGS -rdynamic"
+ ;;
+ esac
+ ;;
+ esac
+ fi
fi
])
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- abort-debug: Prefer libbacktrace to execinfo,
Bruno Haible <=