While the 'abort-debug' module is nice, some users may want to have a print_stack_trace facility that does not come with an override of abort().
This series of patches implements this. 2024-07-17 Bruno Haible <br...@clisp.org> stack-trace: Add tests. * tests/test-stack-trace.c: New file. * modules/stack-trace-tests: New file. stack-trace: New module. * lib/stdlib.in.h (print_stack_trace): Make part of the stack-trace module. * lib/stack-trace-impl.h: New file, based on lib/abort-debug.c. * lib/stack-trace.c: New file, based on lib/abort-debug.c. * lib/abort-debug.c: Include stack-trace-impl.h. Remove definitions moved to stack-trace-impl.h. (print_stack_trace): Remove function. * m4/stdlib_h.m4 (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize GNULIB_STACK_TRACE. (gl_STDLIB_H_DEFAULTS): Initialize CAN_PRINT_STACK_TRACE. * m4/stack-trace.m4: New file, based on m4/abort-debug.m4. * m4/abort-debug.m4 (gl_ABORT_DEBUG_EARLY): Remove macro. (gl_ABORT_DEBUG): Require gl_STDLIB_H_DEFAULTS, gl_STACK_TRACE_EARLY. Set REPLACE_ABORT here. * modules/stdlib (Makefile.am): Substitute GNULIB_STACK_TRACE, CAN_PRINT_STACK_TRACE. * modules/stack-trace: New file. * modules/abort-debug (Depends-on): Add stack-trace. Remove execinfo. (configure.ac-early): Remove section. * DEPENDENCIES: Update. 2024-07-17 Bruno Haible <br...@clisp.org> abort-debug: Export the print_stack_trace function. * lib/stdlib.in.h (print_stack_trace): Renamed from _gl_pre_abort. * lib/abort-debug.c (print_stack_trace_to): Renamed from print_stack_trace. (print_stack_trace): Renamed from _gl_pre_abort. (rpl_abort): Update. * tests/macros.h (ASSERT, ASSERT_NO_STDIO): Update.
>From 5e2115332873c8b802afa5d67a3bff1b5fbba2cd Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 18 Jul 2024 03:07:30 +0200 Subject: [PATCH 1/3] abort-debug: Export the print_stack_trace function. * lib/stdlib.in.h (print_stack_trace): Renamed from _gl_pre_abort. * lib/abort-debug.c (print_stack_trace_to): Renamed from print_stack_trace. (print_stack_trace): Renamed from _gl_pre_abort. (rpl_abort): Update. * tests/macros.h (ASSERT, ASSERT_NO_STDIO): Update. --- ChangeLog | 10 ++++++++++ lib/abort-debug.c | 12 ++++++------ lib/stdlib.in.h | 8 ++++---- tests/macros.h | 4 ++-- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index b80ca078d5..7b39f40541 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2024-07-17 Bruno Haible <br...@clisp.org> + + abort-debug: Export the print_stack_trace function. + * lib/stdlib.in.h (print_stack_trace): Renamed from _gl_pre_abort. + * lib/abort-debug.c (print_stack_trace_to): Renamed from + print_stack_trace. + (print_stack_trace): Renamed from _gl_pre_abort. + (rpl_abort): Update. + * tests/macros.h (ASSERT, ASSERT_NO_STDIO): Update. + 2024-07-17 Bruno Haible <br...@clisp.org> doc: List library dependencies. diff --git a/lib/abort-debug.c b/lib/abort-debug.c index 8252b66def..641fceee2d 100644 --- a/lib/abort-debug.c +++ b/lib/abort-debug.c @@ -31,7 +31,7 @@ static inline void # if (__GNUC__ >= 3) || (__clang_major__ >= 4) __attribute__ ((always_inline)) # endif -print_stack_trace (FILE *stream) +print_stack_trace_to (FILE *stream) { if (state == NULL) state = backtrace_create_state (NULL, 0, NULL, NULL); @@ -50,7 +50,7 @@ static inline void # if (__GNUC__ >= 3) || (__clang_major__ >= 4) __attribute__ ((always_inline)) # endif -print_stack_trace (FILE *stream) +print_stack_trace_to (FILE *stream) { void *buffer[100]; int max_size = sizeof (buffer) / sizeof (buffer[0]); @@ -75,23 +75,23 @@ print_stack_trace (FILE *stream) #endif void -_gl_pre_abort (void) +print_stack_trace (void) { #if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H - print_stack_trace (stderr); + print_stack_trace_to (stderr); #endif } /* rpl_abort (); is equivalent to - _gl_pre_abort (); + print_stack_trace (); original abort (); // i.e. raise (SIGABRT); */ void rpl_abort (void) { #if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H - print_stack_trace (stderr); + print_stack_trace_to (stderr); #endif raise (SIGABRT); } diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index e42368eef2..82e8dcd258 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -256,11 +256,11 @@ _GL_CXXALIASWARN (abort); # endif #endif #if @GNULIB_ABORT_DEBUG@ && @REPLACE_ABORT@ -_GL_EXTERN_C void _gl_pre_abort (void); +_GL_EXTERN_C void print_stack_trace (void); #else -# if !GNULIB_defined_gl_pre_abort -# define _gl_pre_abort() /* nothing */ -# define GNULIB_defined_gl_pre_abort 1 +# if !GNULIB_defined_print_stack_trace +# define print_stack_trace() /* nothing */ +# define GNULIB_defined_print_stack_trace 1 # endif #endif diff --git a/tests/macros.h b/tests/macros.h index 144905e031..3121b21820 100644 --- a/tests/macros.h +++ b/tests/macros.h @@ -82,7 +82,7 @@ int volatile test_exit_status = EXIT_SUCCESS; fflush (ASSERT_STREAM); \ if (CONTINUE_AFTER_ASSERT) \ { \ - _gl_pre_abort (); \ + print_stack_trace (); \ test_exit_status = EXIT_FAILURE; \ } \ else \ @@ -106,7 +106,7 @@ int volatile test_exit_status = EXIT_SUCCESS; WRITE_TO_STDERR ("' failed\n"); \ if (CONTINUE_AFTER_ASSERT) \ { \ - _gl_pre_abort (); \ + print_stack_trace (); \ test_exit_status = EXIT_FAILURE; \ } \ else \ -- 2.34.1
>From 97897a6a4216121aab13414421cc74f01cf06489 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 18 Jul 2024 04:04:23 +0200 Subject: [PATCH 2/3] stack-trace: New module. * lib/stdlib.in.h (print_stack_trace): Make part of the stack-trace module. * lib/stack-trace-impl.h: New file, based on lib/abort-debug.c. * lib/stack-trace.c: New file, based on lib/abort-debug.c. * lib/abort-debug.c: Include stack-trace-impl.h. Remove definitions moved to stack-trace-impl.h. (print_stack_trace): Remove function. * m4/stdlib_h.m4 (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize GNULIB_STACK_TRACE. (gl_STDLIB_H_DEFAULTS): Initialize CAN_PRINT_STACK_TRACE. * m4/stack-trace.m4: New file, based on m4/abort-debug.m4. * m4/abort-debug.m4 (gl_ABORT_DEBUG_EARLY): Remove macro. (gl_ABORT_DEBUG): Require gl_STDLIB_H_DEFAULTS, gl_STACK_TRACE_EARLY. Set REPLACE_ABORT here. * modules/stdlib (Makefile.am): Substitute GNULIB_STACK_TRACE, CAN_PRINT_STACK_TRACE. * modules/stack-trace: New file. * modules/abort-debug (Depends-on): Add stack-trace. Remove execinfo. (configure.ac-early): Remove section. * DEPENDENCIES: Update. --- ChangeLog | 24 +++++++++++++ DEPENDENCIES | 2 +- lib/abort-debug.c | 61 +------------------------------ lib/stack-trace-impl.h | 68 +++++++++++++++++++++++++++++++++++ lib/stack-trace.c | 30 ++++++++++++++++ lib/stdlib.in.h | 17 ++++----- m4/abort-debug.m4 | 77 ++++----------------------------------- m4/stack-trace.m4 | 81 ++++++++++++++++++++++++++++++++++++++++++ m4/stdlib_h.m4 | 4 ++- modules/abort-debug | 6 +--- modules/stack-trace | 34 ++++++++++++++++++ modules/stdlib | 2 ++ 12 files changed, 260 insertions(+), 146 deletions(-) create mode 100644 lib/stack-trace-impl.h create mode 100644 lib/stack-trace.c create mode 100644 m4/stack-trace.m4 create mode 100644 modules/stack-trace diff --git a/ChangeLog b/ChangeLog index 7b39f40541..3f3d820c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2024-07-17 Bruno Haible <br...@clisp.org> + + stack-trace: New module. + * lib/stdlib.in.h (print_stack_trace): Make part of the stack-trace + module. + * lib/stack-trace-impl.h: New file, based on lib/abort-debug.c. + * lib/stack-trace.c: New file, based on lib/abort-debug.c. + * lib/abort-debug.c: Include stack-trace-impl.h. Remove definitions + moved to stack-trace-impl.h. + (print_stack_trace): Remove function. + * m4/stdlib_h.m4 (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize + GNULIB_STACK_TRACE. + (gl_STDLIB_H_DEFAULTS): Initialize CAN_PRINT_STACK_TRACE. + * m4/stack-trace.m4: New file, based on m4/abort-debug.m4. + * m4/abort-debug.m4 (gl_ABORT_DEBUG_EARLY): Remove macro. + (gl_ABORT_DEBUG): Require gl_STDLIB_H_DEFAULTS, gl_STACK_TRACE_EARLY. + Set REPLACE_ABORT here. + * modules/stdlib (Makefile.am): Substitute GNULIB_STACK_TRACE, + CAN_PRINT_STACK_TRACE. + * modules/stack-trace: New file. + * modules/abort-debug (Depends-on): Add stack-trace. Remove execinfo. + (configure.ac-early): Remove section. + * DEPENDENCIES: Update. + 2024-07-17 Bruno Haible <br...@clisp.org> abort-debug: Export the print_stack_trace function. diff --git a/DEPENDENCIES b/DEPENDENCIES index ce9cf9fb80..fa3bbeb626 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -300,7 +300,7 @@ Libraries Various modules work best with certain libraries installed. These are runtime dependencies that are also build dependencies. -For module 'abort-debug': +For modules 'abort-debug' and 'stack-trace': * libbacktrace + Recommended. Needed for producing C stack traces with source file names and diff --git a/lib/abort-debug.c b/lib/abort-debug.c index 641fceee2d..ac5ddf15cd 100644 --- a/lib/abort-debug.c +++ b/lib/abort-debug.c @@ -21,66 +21,7 @@ #include <signal.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_to (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> - -# include "execinfo.h" - -static inline void -# if (__GNUC__ >= 3) || (__clang_major__ >= 4) -__attribute__ ((always_inline)) -# endif -print_stack_trace_to (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 -print_stack_trace (void) -{ -#if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H - print_stack_trace_to (stderr); -#endif -} +#include "stack-trace-impl.h" /* rpl_abort (); is equivalent to diff --git a/lib/stack-trace-impl.h b/lib/stack-trace-impl.h new file mode 100644 index 0000000000..018563e4cc --- /dev/null +++ b/lib/stack-trace-impl.h @@ -0,0 +1,68 @@ +/* print_stack_trace() function that prints a stack trace. + 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/>. */ + +#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_to (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> + +# include "execinfo.h" + +static inline void +# if (__GNUC__ >= 3) || (__clang_major__ >= 4) +__attribute__ ((always_inline)) +# endif +print_stack_trace_to (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 diff --git a/lib/stack-trace.c b/lib/stack-trace.c new file mode 100644 index 0000000000..b4ad37bf78 --- /dev/null +++ b/lib/stack-trace.c @@ -0,0 +1,30 @@ +/* print_stack_trace() function that prints a stack trace. + 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 "stack-trace-impl.h" + +void +print_stack_trace (void) +{ +#if HAVE_LIBBACKTRACE || HAVE_EXECINFO_H + print_stack_trace_to (stderr); +#endif +} diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 82e8dcd258..3de9eba245 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -255,14 +255,6 @@ _GL_CXXALIAS_SYS (abort, void, (void)); _GL_CXXALIASWARN (abort); # endif #endif -#if @GNULIB_ABORT_DEBUG@ && @REPLACE_ABORT@ -_GL_EXTERN_C void print_stack_trace (void); -#else -# if !GNULIB_defined_print_stack_trace -# define print_stack_trace() /* nothing */ -# define GNULIB_defined_print_stack_trace 1 -# endif -#endif #if @GNULIB_FREE_POSIX@ @@ -1608,6 +1600,15 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - " # endif #endif +#if @GNULIB_STACK_TRACE@ && @CAN_PRINT_STACK_TRACE@ +_GL_EXTERN_C void print_stack_trace (void); +#else +# if !GNULIB_defined_print_stack_trace +# define print_stack_trace() /* nothing */ +# define GNULIB_defined_print_stack_trace 1 +# endif +#endif + #if @GNULIB_STRTOD@ /* Parse a double from STRING, updating ENDP if appropriate. */ # if @REPLACE_STRTOD@ diff --git a/m4/abort-debug.m4 b/m4/abort-debug.m4 index 61716e5a06..9d4c4c8c73 100644 --- a/m4/abort-debug.m4 +++ b/m4/abort-debug.m4 @@ -1,81 +1,16 @@ # abort-debug.m4 -# serial 2 +# serial 3 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_DEFUN([gl_ABORT_DEBUG], [ - 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 - 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 + AC_REQUIRE([gl_STACK_TRACE_EARLY]) + if test $CAN_PRINT_STACK_TRACE = 1; then + REPLACE_ABORT=1 + AC_REQUIRE([AC_C_INLINE]) fi ]) - -AC_DEFUN([gl_ABORT_DEBUG], -[ - AC_REQUIRE([AC_C_INLINE]) -]) diff --git a/m4/stack-trace.m4 b/m4/stack-trace.m4 new file mode 100644 index 0000000000..7184ca7eb2 --- /dev/null +++ b/m4/stack-trace.m4 @@ -0,0 +1,81 @@ +# stack-trace.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_STACK_TRACE_EARLY], +[ + AC_MSG_CHECKING([whether to enable debugging facilities]) + AC_ARG_ENABLE([debug], + [AS_HELP_STRING([[--disable-debug]], + [turn off debugging facilities])], + [case "$enableval" in + yes | no) ;; + *) AC_MSG_WARN([invalid argument supplied to --enable-debug]) + enable_debug=yes + ;; + esac + ], + [enable_debug=yes]) + AC_MSG_RESULT([$enable_debug]) + + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + if test $enable_debug = yes; then + 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.]) + 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 + fi + fi +]) + +AC_DEFUN([gl_STACK_TRACE], +[ + AC_REQUIRE([AC_C_INLINE]) +]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index bb5a646041..332669f946 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,5 +1,5 @@ # stdlib_h.m4 -# serial 78 +# serial 79 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, @@ -146,6 +146,7 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS] gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STACK_TRACE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL]) @@ -261,4 +262,5 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS] REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL]) REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) + CAN_PRINT_STACK_TRACE=0; AC_SUBST([CAN_PRINT_STACK_TRACE]) ]) diff --git a/modules/abort-debug b/modules/abort-debug index 56cbdac5be..5bbe64e372 100644 --- a/modules/abort-debug +++ b/modules/abort-debug @@ -7,11 +7,7 @@ m4/abort-debug.m4 Depends-on: stdlib -execinfo - -configure.ac-early: -AC_REQUIRE([gl_ABORT_DEBUG_EARLY]) -export LDFLAGS +stack-trace configure.ac: gl_ABORT_DEBUG diff --git a/modules/stack-trace b/modules/stack-trace new file mode 100644 index 0000000000..122845d610 --- /dev/null +++ b/modules/stack-trace @@ -0,0 +1,34 @@ +Description: +print_stack_trace() function that prints a stack trace. + +Files: +lib/stack-trace-impl.h +lib/stack-trace.c +m4/stack-trace.m4 + +Depends-on: +stdlib +execinfo + +configure.ac-early: +AC_REQUIRE([gl_STACK_TRACE_EARLY]) +export LDFLAGS + +configure.ac: +gl_STACK_TRACE +gl_CONDITIONAL([GL_COND_OBJ_STACK_TRACE], [test $CAN_PRINT_STACK_TRACE = 1]) +gl_STDLIB_MODULE_INDICATOR([stack-trace]) + +Makefile.am: +if GL_COND_OBJ_STACK_TRACE +lib_SOURCES += stack-trace.c +endif + +Include: +<stdlib.h> + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/stdlib b/modules/stdlib index 4e2b0ff32a..009dec8ee6 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -73,6 +73,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STACK_TRACE''@/$(GNULIB_STACK_TRACE)/g' \ -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ -e 's/@''GNULIB_STRTOF''@/$(GNULIB_STRTOF)/g' \ -e 's/@''GNULIB_STRTOL''@/$(GNULIB_STRTOL)/g' \ @@ -182,6 +183,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \ -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ + -e 's|@''CAN_PRINT_STACK_TRACE''@|$(CAN_PRINT_STACK_TRACE)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _Noreturn/r $(_NORETURN_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -- 2.34.1
>From 0c9a86430dc0a20cb6bc312711f7d2eb115bd1fd Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 18 Jul 2024 04:15:34 +0200 Subject: [PATCH 3/3] stack-trace: Add tests. * tests/test-stack-trace.c: New file. * modules/stack-trace-tests: New file. --- ChangeLog | 4 ++++ modules/stack-trace-tests | 11 +++++++++++ tests/test-stack-trace.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 modules/stack-trace-tests create mode 100644 tests/test-stack-trace.c diff --git a/ChangeLog b/ChangeLog index 3f3d820c2b..b1ee1b8e62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2024-07-17 Bruno Haible <br...@clisp.org> + stack-trace: Add tests. + * tests/test-stack-trace.c: New file. + * modules/stack-trace-tests: New file. + stack-trace: New module. * lib/stdlib.in.h (print_stack_trace): Make part of the stack-trace module. diff --git a/modules/stack-trace-tests b/modules/stack-trace-tests new file mode 100644 index 0000000000..eac93a9062 --- /dev/null +++ b/modules/stack-trace-tests @@ -0,0 +1,11 @@ +Files: +tests/test-stack-trace.c +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-stack-trace +check_PROGRAMS += test-stack-trace diff --git a/tests/test-stack-trace.c b/tests/test-stack-trace.c new file mode 100644 index 0000000000..a83efc700c --- /dev/null +++ b/tests/test-stack-trace.c @@ -0,0 +1,36 @@ +/* Test of print_stack_trace() function. + Copyright (C) 2024 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <br...@clisp.org>, 2024. */ + +#include <config.h> + +/* Specification. */ +#include <stdlib.h> + +static void +test_something (void) +{ + print_stack_trace (); +} + +int +main (int argc, char *argv[]) +{ + test_something (); + + return 0; +} -- 2.34.1