* lib/stdlib.in.h (abort): New declaration.
* lib/abort-debug.c: New file.
* m4/abort-debug.m4: New file.
* modules/abort-debug: New file.
* m4/stdlib_h.m4 (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize
GNULIB_ABORT_DEBUG.
(gl_STDLIB_H_DEFAULTS): Initialize REPLACE_ABORT.
* modules/stdlib (Makefile.am): Substitute GNULIB_ABORT_DEBUG,
REPLACE_ABORT.
+2024-05-17 Bruno Haible <bruno@clisp.org>
+
+ New module 'abort-debug'.
+ * lib/stdlib.in.h (abort): New declaration.
+ * lib/abort-debug.c: New file.
+ * m4/abort-debug.m4: New file.
+ * modules/abort-debug: New file.
+ * m4/stdlib_h.m4 (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize
+ GNULIB_ABORT_DEBUG.
+ (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_ABORT.
+ * modules/stdlib (Makefile.am): Substitute GNULIB_ABORT_DEBUG,
+ REPLACE_ABORT.
+
2024-05-17 Bruno Haible <bruno@clisp.org>
execinfo: Update doc.
--- /dev/null
+/* abort() function that prints a stack trace before aborting.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <signal.h>
+
+#if HAVE_EXECINFO_H
+
+# include <stdio.h>
+
+# include "execinfo.h"
+
+static inline void
+# if (__GNUC__ >= 3) || (__clang_major__ >= 4)
+__attribute__ ((always_inline))
+# endif
+print_stack_trace (FILE *stream)
+{
+ void *buffer[100];
+ int max_size = sizeof (buffer) / sizeof (buffer[0]);
+ int size = backtrace (buffer, max_size);
+ if (size > 0)
+ {
+ char **symbols = backtrace_symbols (buffer, size);
+ if (symbols != NULL)
+ {
+ int i;
+
+ fprintf (stream, "Stack trace:\n");
+ for (i = 0; i < size; i++)
+ fprintf (stream, "%s\n", symbols[i]);
+ fflush (stream);
+
+ free (symbols);
+ }
+ }
+}
+
+#endif
+
+void
+rpl_abort (void)
+{
+#if HAVE_EXECINFO_H
+ print_stack_trace (stderr);
+#endif
+ raise (SIGABRT);
+}
#endif
+#if @GNULIB_ABORT_DEBUG@
+# if @REPLACE_ABORT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef abort
+# define abort rpl_abort
+# endif
+_GL_FUNCDECL_RPL (abort, _Noreturn void, (void));
+_GL_CXXALIAS_RPL (abort, void, (void));
+# else
+_GL_CXXALIAS_SYS (abort, void, (void));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (abort);
+# endif
+#endif
+
+
#if @GNULIB_FREE_POSIX@
# if @REPLACE_FREE@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
--- /dev/null
+# abort-debug.m4
+# serial 1
+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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_ABORT_DEBUG_EARLY],
+[
+ AC_MSG_CHECKING([whether to enable debugging facilities on abort])
+ AC_ARG_ENABLE([debug-abort],
+ [AS_HELP_STRING([[--disable-debug-abort]],
+ [turn off debugging facilities])],
+ [case "$enableval" in
+ yes | no) ;;
+ *) AC_MSG_WARN([invalid argument supplied to --enable-debug-abort])
+ enable_debug_abort=yes
+ ;;
+ esac
+ ],
+ [enable_debug_abort=yes])
+ AC_MSG_RESULT([$enable_debug_abort])
+
+ 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
+ fi
+])
+
+AC_DEFUN([gl_ABORT_DEBUG],
+[
+ AC_REQUIRE([AC_C_INLINE])
+])
# stdlib_h.m4
-# serial 77
+# serial 78
dnl Copyright (C) 2007-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,
[
m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ABORT_DEBUG])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_GNU])
HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT])
HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV])
REPLACE__EXIT=0; AC_SUBST([REPLACE__EXIT])
+ REPLACE_ABORT=0; AC_SUBST([REPLACE_ABORT])
REPLACE_ALIGNED_ALLOC=0; AC_SUBST([REPLACE_ALIGNED_ALLOC])
REPLACE_CALLOC_FOR_CALLOC_GNU=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_GNU])
REPLACE_CALLOC_FOR_CALLOC_POSIX=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_POSIX])
--- /dev/null
+Description:
+abort() function that prints a stack trace before aborting.
+
+Files:
+lib/abort-debug.c
+m4/abort-debug.m4
+
+Depends-on:
+stdlib
+execinfo
+
+configure.ac-early:
+AC_REQUIRE([gl_ABORT_DEBUG_EARLY])
+export LDFLAGS
+
+configure.ac:
+gl_ABORT_DEBUG
+gl_CONDITIONAL([GL_COND_OBJ_ABORT_DEBUG], [test $REPLACE_ABORT = 1])
+gl_STDLIB_MODULE_INDICATOR([abort-debug])
+
+Makefile.am:
+if GL_COND_OBJ_ABORT_DEBUG
+lib_SOURCES += abort-debug.c
+endif
+
+Include:
+<stdlib.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
-e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \
+ -e 's/@''GNULIB_ABORT_DEBUG''@/$(GNULIB_ABORT_DEBUG)/g' \
-e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GNULIB_ALIGNED_ALLOC)/g' \
-e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \
-e 's/@''GNULIB_CALLOC_GNU''@/$(GNULIB_CALLOC_GNU)/g' \
< $@-t1 > $@-t2
$(AM_V_at)sed \
-e 's|@''REPLACE__EXIT''@|$(REPLACE__EXIT)|g' \
+ -e 's|@''REPLACE_ABORT''@|$(REPLACE_ABORT)|g' \
-e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \
-e 's|@''REPLACE_CALLOC_FOR_CALLOC_GNU''@|$(REPLACE_CALLOC_FOR_CALLOC_GNU)|g' \
-e 's|@''REPLACE_CALLOC_FOR_CALLOC_POSIX''@|$(REPLACE_CALLOC_FOR_CALLOC_POSIX)|g' \