]> Savannah Git Hosting - gnulib.git/commitdiff
stack-trace: New module.
authorBruno Haible <bruno@clisp.org>
Thu, 18 Jul 2024 02:04:23 +0000 (04:04 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 18 Jul 2024 02:11:05 +0000 (04:11 +0200)
* 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.

12 files changed:
ChangeLog
DEPENDENCIES
lib/abort-debug.c
lib/stack-trace-impl.h [new file with mode: 0644]
lib/stack-trace.c [new file with mode: 0644]
lib/stdlib.in.h
m4/abort-debug.m4
m4/stack-trace.m4 [new file with mode: 0644]
m4/stdlib_h.m4
modules/abort-debug
modules/stack-trace [new file with mode: 0644]
modules/stdlib

index 7b39f40541ee67f9c1dfcfb2b508f9bf413ef623..3f3d820c2bce0759b510f78dccd6cc2450e8aac6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2024-07-17  Bruno Haible  <bruno@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  <bruno@clisp.org>
 
        abort-debug: Export the print_stack_trace function.
index ce9cf9fb80d2e63b50102a0a0d52d490846f5b36..fa3bbeb62667fe28c08d988778065d96947be0bf 100644 (file)
@@ -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
index 641fceee2dc223423f513cd554baf3672bcd948a..ac5ddf15cd75e6d31c9c034e3ea2259166d00f57 100644 (file)
 
 #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 (file)
index 0000000..018563e
--- /dev/null
@@ -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 (file)
index 0000000..b4ad37b
--- /dev/null
@@ -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
+}
index 82e8dcd258cea9fb9ee353800032ed9b19413bad..3de9eba245a12e86d296f01c4b6ae934f41dafc6 100644 (file)
@@ -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@
index 61716e5a0667e7db6b6ea4875fd5f92d7f660b50..9d4c4c8c73570e906dc62795b2832e017be686e7 100644 (file)
@@ -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 (file)
index 0000000..7184ca7
--- /dev/null
@@ -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])
+])
index bb5a6460414f7551dae5b7f8a6fa481aa640bca0..332669f94672aebcd5c3d122a00134538a2a7963 100644 (file)
@@ -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])
 ])
index 56cbdac5be8fda95b8b2463c3f95b88ef02f6f14..5bbe64e3722d6ebe44ecad62ab5ad78d196935c9 100644 (file)
@@ -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 (file)
index 0000000..122845d
--- /dev/null
@@ -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
index 4e2b0ff32a55a83499e50079b4193fc23f7a40a3..009dec8ee64aef73dcbf01858924609c919ad8e6 100644 (file)
@@ -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)' \