+2024-07-17 Bruno Haible <bruno@clisp.org>
+
+ stack-trace: Use libasan as an alternative to libbacktrace.
+ * m4/stack-trace.m4 (gl_STACK_TRACE_EARLY): As a second choice, use
+ libasan.
+ * lib/stack-trace-impl.h (print_stack_trace_to) [HAVE_LIBASAN]:
+ Implement using libasan.
+ * lib/stack-trace.c (print_stack_trace): Test also HAVE_LIBASAN.
+ * lib/abort-debug.c (rpl_abort): Likewise.
+
2024-07-17 Bruno Haible <bruno@clisp.org>
stack-trace: Add tests.
{
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");
+ /* Pass skip=0, to work around <https://github.com/ianlancetaylor/libbacktrace/issues/60>. */
backtrace_print (state, 0, stream);
}
+#elif HAVE_LIBASAN
+
+# include <stdio.h>
+
+/* We need only one declaration from <sanitizer/asan_interface.h>. */
+extern
+# ifdef __cplusplus
+"C"
+# endif
+void __sanitizer_print_stack_trace (void);
+
+/* The only supported stream, in this case, is stderr. */
+static inline void
+# if (__GNUC__ >= 3) || (__clang_major__ >= 4)
+__attribute__ ((always_inline))
+# endif
+print_stack_trace_to (FILE *stream)
+{
+ fprintf (stream, "Stack trace:\n");
+ __sanitizer_print_stack_trace ();
+}
+
#elif HAVE_EXECINFO_H
# include <stdio.h>
# stack-trace.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,
CAN_PRINT_STACK_TRACE=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.
- CAN_PRINT_STACK_TRACE=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
+ dnl The second choice is GCC's libasan, installed as part of GCC.
+ dnl It produces source file names and line numbers, if the binary
+ dnl is compiled with debug information.
+ AC_CACHE_CHECK([for libasan], [gl_cv_lib_asan], [
+ gl_saved_LIBS="$LIBS"
+ LIBS="$gl_saved_LIBS -lasan"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[extern
+ #ifdef __cplusplus
+ "C"
+ #endif
+ void __sanitizer_print_stack_trace (void);
+ ]],
+ [[__sanitizer_print_stack_trace ();
+ ]])],
+ [gl_cv_lib_asan=yes],
+ [gl_cv_lib_asan=no])
+ LIBS="$gl_saved_LIBS"
+ ])
+ if test $gl_cv_lib_asan = yes; then
+ AC_DEFINE([HAVE_LIBASAN], [1],
+ [Define if you have the libasan library.])
+ CAN_PRINT_STACK_TRACE=1
+ LIBS="$LIBS -lasan"
+ else
+ dnl The third 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.
+ CAN_PRINT_STACK_TRACE=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
fi
])