* [musl] [PATCH] Add options to configure script to control frame pointer omission and EH unwind information
@ 2023-07-28 11:13 Alastair Houghton
2023-07-29 5:25 ` alice
0 siblings, 1 reply; 3+ messages in thread
From: Alastair Houghton @ 2023-07-28 11:13 UTC (permalink / raw)
To: musl
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [musl] [PATCH] Add options to configure script to control frame pointer omission and EH unwind information
2023-07-28 11:13 [musl] [PATCH] Add options to configure script to control frame pointer omission and EH unwind information Alastair Houghton
@ 2023-07-29 5:25 ` alice
2023-07-31 14:15 ` Alastair Houghton
0 siblings, 1 reply; 3+ messages in thread
From: alice @ 2023-07-29 5:25 UTC (permalink / raw)
To: musl
On Fri Jul 28, 2023 at 11:13 AM UTC, Alastair Houghton wrote:
> 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.
i believe the proposed change, and the rationale for it, had already been
thoroughly discussed and rejected in
https://www.openwall.com/lists/musl/2021/07/16/1
(not exactly the same, and the above isn't as fine grained, but the core of it
is identical)
the core of it is really in (quoting Rich):
> The debugger already can do debugging/unwinding because it has access
> to the debug information (if you've installed it) and there is a
> clear, understood-by-users contract that this information is not an
> inherent part of the program but something optional for external
> debugging tools only.
>> - libunwind/libexecinfo will start to work and give meaningful backtraces
>
> This is explicitly a reason not to. backtrace() considered harmful.
there is no intent to allow 'runtime use' of this data (i.e. allow backtraces),
outside of what already works with an external debugger.
unrelatedly (to the prior rejection), i believe these days there has been work
on the SFrame format (as opposed to EH), to allow easier backtracing (they
aren't mutually exclusive). maybe that is better to build on these days?
>
> Kind regards,
>
> Alastair.
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [musl] [PATCH] Add options to configure script to control frame pointer omission and EH unwind information
2023-07-29 5:25 ` alice
@ 2023-07-31 14:15 ` Alastair Houghton
0 siblings, 0 replies; 3+ messages in thread
From: Alastair Houghton @ 2023-07-31 14:15 UTC (permalink / raw)
To: musl
> On 29 Jul 2023, at 06:25, alice <alice@ayaya.dev> wrote:
>
> i believe the proposed change, and the rationale for it, had already been
> thoroughly discussed and rejected in
> https://www.openwall.com/lists/musl/2021/07/16/1
Thanks for the link. That was an interesting read.
> there is no intent to allow 'runtime use' of this data (i.e. allow backtraces),
> outside of what already works with an external debugger.
It’s worth noting (and I think the Alpine folks did mention this in the thread you highlighted) that external debuggers don’t work inside Docker containers, at least by default, and that that cluster operators are unlikely to want to make the changes that would be required to fix that because they create security holes.
At the same time, generating backtraces in e.g. assertion failure routines or from a C++ unhandled exception handler can be a useful thing to do and is not nearly as risky as trying to do that from a SEGV handler. With no EH frame information and no frame pointers, those backtraces are going to stop the moment they hit musl’s code. Maybe that’s OK — there aren’t that many things in the C library that involve calling out to user code anyway.
> unrelatedly (to the prior rejection), i believe these days there has been work
> on the SFrame format (as opposed to EH), to allow easier backtracing (they
> aren't mutually exclusive). maybe that is better to build on these days?
As I understand it that’s a Linux kernel thing, and not really applicable outside of that context.
What I was mostly trying to do is get (LLVM) libunwind’s tests to pass out of the box, without having to disable things for musl. Maybe I just disable those tests for now.
Kind regards,
Alastair.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-07-31 14:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-28 11:13 [musl] [PATCH] Add options to configure script to control frame pointer omission and EH unwind information Alastair Houghton
2023-07-29 5:25 ` alice
2023-07-31 14:15 ` Alastair Houghton
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).