Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 28 Jul 2023 12:13:40 +0100
From: Alastair Houghton <ahoughton@...le.com>
To: musl@...ts.openwall.com
Subject: [PATCH] Add options to configure script to control frame pointer
 omission and EH unwind information

Hi there,

Musl currently disables frame pointers and (except in debug builds) also disables the emission of EH unwind information, the latter presumably in an effort to save space. The downside of doing both of these things is that it makes it impossible for code to generate reasonable run-time backtraces, since without frame pointers the only way to do a stack walk is the EH unwind data, which has been removed.

These defaults are probably fine for most people, but not everybody wants to build in this configuration, and it would be better to offer some reasonable options here, I think. I attach a patch that adds options to the configure script that allow users of Musl to choose

* Whether to include frame pointers.
* Whether to include EH unwind tables, and if so whether they should support asynchronous unwind or not (asynchronous unwind generates more data in the tables, since the compiler isn’t allowed to make assumptions about which code could throw).

Note that the existing comment in the configure script about the DWARF tables is slightly misleading; the options the configure script uses are to do with EH unwind data (which is for exception handling, in languages that support it, as well as for runtime backtracing), and not with DWARF unwind data.  The two do potentially share some sections and the EH data is stored using DWARF as a format, but it *isn’t* debug information - it’s there for language runtime and library use.

Kind regards,

Alastair.

==== Patch follows ====

diff --git a/configure b/configure
index 853bf05e..a11e0ad8 100755
--- a/configure
+++ b/configure
@@ -10,39 +10,42 @@ VAR=VALUE.  See below for descriptions of some of the useful variables.
 Defaults for the options are specified in brackets.
 
 Configuration:
-  --srcdir=DIR            source directory [detected]
+  --srcdir=DIR             source directory [detected]
 
 Installation directories:
-  --prefix=PREFIX         main installation prefix [/usr/local/musl]
-  --exec-prefix=EPREFIX   installation prefix for executable files [PREFIX]
+  --prefix=PREFIX          main installation prefix [/usr/local/musl]
+  --exec-prefix=EPREFIX    installation prefix for executable files [PREFIX]
 
 Fine tuning of the installation directories:
-  --bindir=DIR            user executables [EPREFIX/bin]
-  --libdir=DIR            library files for the linker [PREFIX/lib]
-  --includedir=DIR        include files for the C compiler [PREFIX/include]
-  --syslibdir=DIR         location for the dynamic linker [/lib]
+  --bindir=DIR             user executables [EPREFIX/bin]
+  --libdir=DIR             library files for the linker [PREFIX/lib]
+  --includedir=DIR         include files for the C compiler [PREFIX/include]
+  --syslibdir=DIR          location for the dynamic linker [/lib]
 
 System types:
-  --target=TARGET         configure to run on target TARGET [detected]
-  --host=HOST             same as --target
-  --build=BUILD           build system type; used only to infer cross-compiling
+  --target=TARGET          configure to run on target TARGET [detected]
+  --host=HOST              same as --target
+  --build=BUILD            build system type; used only to infer cross-compiling
 
 Optional features:
-  --enable-optimize=...   optimize listed components for speed over size [auto]
-  --enable-debug          build with debugging information [disabled]
-  --disable-warnings      build with recommended warnings flags [enabled]
-  --enable-wrapper=...    build given musl toolchain wrapper [auto]
-  --disable-shared        inhibit building shared library [enabled]
-  --disable-static        inhibit building static library [enabled]
+  --enable-optimize=...    optimize listed components for speed over size [auto]
+  --enable-debug           build with debugging information [disabled]
+  --disable-warnings       build with recommended warnings flags [enabled]
+  --enable-wrapper=...     build given musl toolchain wrapper [auto]
+  --disable-shared         inhibit building shared library [enabled]
+  --disable-static         inhibit building static library [enabled]
+  --with-frame-pointers    disable -fomit-frame-pointer [disabled]
+  --with-unwind-tables=... generate EH unwind inforormation [none]
+                           (may be "none", "sync" or "async")
 
 Optional packages:
-  --with-malloc=...       choose malloc implementation [mallocng]
+  --with-malloc=...        choose malloc implementation [mallocng]
 
 Some influential environment variables:
-  CC                      C compiler command [detected]
-  CFLAGS                  C compiler flags [-Os -pipe ...]
-  CROSS_COMPILE           prefix for cross compiler and tools [none]
-  LIBCC                   compiler runtime library [detected]
+  CC                       C compiler command [detected]
+  CFLAGS                   C compiler flags [-Os -pipe ...]
+  CROSS_COMPILE            prefix for cross compiler and tools [none]
+  LIBCC                    compiler runtime library [detected]
 
 Use these variables to override the choices made by configure.
 
@@ -143,6 +146,8 @@ wrapper=auto
 gcc_wrapper=no
 clang_wrapper=no
 malloc_dir=mallocng
+frame_pointers=no
+unwind_tables=none
 
 for arg ; do
 case "$arg" in
@@ -172,6 +177,8 @@ case "$arg" in
 --disable-wrapper|--enable-wrapper=no) wrapper=no ;;
 --enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ; gcc_wrapper=yes ;;
 --disable-gcc-wrapper|--enable-gcc-wrapper=no) wrapper=no ;;
+--with-frame-pointers) frame_pointers=yes ;;
+--with-unwind-tables=*) unwind_tables=${arg#*=} ;;
 --with-malloc=*) malloc_dir=${arg#*=} ;;
 --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;;
 --host=*|--target=*) target=${arg#*=} ;;
@@ -471,23 +478,46 @@ fi
 tryflag CFLAGS_AUTO -pipe
 
 #
-# If debugging is disabled, omit frame pointer. Modern GCC does this
-# anyway on most archs even when debugging is enabled since the frame
-# pointer is no longer needed for debugging.
+# Unless otherwise specified, omit frame pointers where possible
+# except when debugging is enabled.
 #
-if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then :
+# In general, either frame pointers or unwind information are required
+# if you wish to be able to obtain a reliable backtrace from a crashed
+# program.
+#
+# Neither is required for debugging, as the full debug information
+# will be used in that case.
+#
+if test "$frame_pointers" = yes ; then
+tryflag CFLAGS_AUTO -fno-omit-frame-pointer
+elif fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then :
 else
 tryflag CFLAGS_AUTO -fomit-frame-pointer
 fi
 
 #
-# Modern GCC wants to put DWARF tables (used for debugging and
-# unwinding) in the loaded part of the program where they are
-# unstrippable. These options force them back to debug sections (and
-# cause them not to get generated at all if debugging is off).
+# Control the generation of unwind information.  Note that this is not
+# used for debugging; in C it is only used to allow runtime backtracing
+# without frame pointers.  In languages with exceptions, it is used to
+# provide instructions to the unwinder (typically libunwind).
 #
+case "$unwind_tables" in
+none|no)
 tryflag CFLAGS_AUTO -fno-unwind-tables
 tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
+;;
+sync|yes)
+tryflag CFLAGS_AUTO -funwind-tables
+tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
+;;
+async)
+tryflag CFLAGS_AUTO -funwind-tables
+tryflag CFLAGS_AUTO -fasynchronous-unwind-tables
+;;
+*)
+fail "$0: error: unknown unwind table settings '$unwind_tables'"
+;;
+esac
 
 #
 # Attempt to put each function and each data object in its own

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.