I did: > 2024-07-17 Bruno Haible <br...@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.
However, on NetBSD 10.0, every program that links with libasan exits without even reaching main(). It merely prints "This sanitizer is not compatible with enabled ASLR" to standard error and exits with status 0 (yes, 0 !!!). NetBSD is such a joke. And yes, they knew about it more than one year before they released NetBSD 10.0 [1] and didn't do anything about it. [1] https://mail-index.netbsd.org/pkgsrc-users/2022/12/17/msg036642.html 2024-07-18 Bruno Haible <br...@clisp.org> stack-trace: Don't use NetBSD's broken libasan. * m4/stack-trace.m4 (gl_STACK_TRACE_EARLY): Test whether a program linked with libasan even minimally works. diff --git a/m4/stack-trace.m4 b/m4/stack-trace.m4 index e102484e0f..faf86eefe9 100644 --- a/m4/stack-trace.m4 +++ b/m4/stack-trace.m4 @@ -22,6 +22,7 @@ AC_DEFUN([gl_STACK_TRACE_EARLY] AC_MSG_RESULT([$enable_debug]) AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) if test $enable_debug = yes; then dnl The first choice is libbacktrace by Ian Lance Taylor. dnl Maintained at https://github.com/ianlancetaylor/libbacktrace, @@ -54,50 +55,69 @@ AC_DEFUN([gl_STACK_TRACE_EARLY] AC_CACHE_CHECK([for libasan], [gl_cv_lib_asan], [ gl_saved_LIBS="$LIBS" LIBS="$gl_saved_LIBS -lasan" - AC_LINK_IFELSE( + dnl We need AC_RUN_IFELSE here, not merely AC_LINK_IFELSE, because on + dnl NetBSD libasan exists but every program that links to it immediately + dnl prints "This sanitizer is not compatible with enabled ASLR" to + dnl standard error and exits with code 0, without even invoking main(). + AC_RUN_IFELSE( [AC_LANG_PROGRAM( - [[extern + [[#include <stdio.h> + extern #ifdef __cplusplus "C" #endif void __sanitizer_print_stack_trace (void); ]], - [[__sanitizer_print_stack_trace (); + [[remove ("conftest.c"); + __sanitizer_print_stack_trace (); ]])], - [gl_cv_lib_asan=yes], - [gl_cv_lib_asan=no]) + [if test -f conftest.c; then + dnl main() was not reached. NetBSD! + gl_cv_lib_asan=no + else + gl_cv_lib_asan=yes + fi + ], + [gl_cv_lib_asan=no], + [case "$host_os" in + netbsd*) gl_cv_lib_asan="guessing no" ;; + *) gl_cv_lib_asan="guessing yes" ;; + esac + ]) 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 + case "$gl_cv_lib_asan" in + *yes) + AC_DEFINE([HAVE_LIBASAN], [1], + [Define if you have the libasan library.]) + CAN_PRINT_STACK_TRACE=1 + LIBS="$LIBS -lasan" + ;; + *) + 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. + 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 + ;; + esac fi fi ])