[pacman-dev] [PATCH] makepkg: optionally attach minimal debuginfo to binaries
Leo Wolf
jclw at jclw.de
Mon Feb 8 21:04:14 UTC 2016
The "minidebug" option adds a .gdb_debugdata section to executables
and shared libraries containing LZMA compressed function symbols. GDB
(and by extension systemd-coredump) can use this information to
display useful backtraces without full debuginfo being installed.
(see https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html)
This benefit comes at the cost of slightly increased binary sizes.
(https://fedoraproject.org/wiki/Features/MiniDebugInfo#Detailed_Description)
Signed-off-by: Leo Wolf <jclw at jclw.de>
---
doc/makepkg.conf.5.txt | 10 +++++++
scripts/libmakepkg/tidy/strip.sh.in | 60 +++++++++++++++++++++++++++++++++----
scripts/makepkg.sh.in | 2 +-
3 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/doc/makepkg.conf.5.txt b/doc/makepkg.conf.5.txt
index e35eb8a..b86fd04 100644
--- a/doc/makepkg.conf.5.txt
+++ b/doc/makepkg.conf.5.txt
@@ -191,6 +191,16 @@ Options
DEBUG_CXXFLAGS to their counterpart buildflags. Creates a separate
package containing the debug symbols when used with `strip'.
+ *minidebug*;;
+ Enable useful backtraces at the cost of slightly larger binaries by
+ adding a section containing compressed function symbols to stripped
+ executables and shared libraries. (see
+ https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html) Like
+ `debug', this option will add the user-specified debug flags as
+ specified in DEBUG_CFLAGS and DEBUG_CXXFLAGS to their counterpart
+ buildflags. `minidebug' is only useful with `strip', but can be used
+ with or without `debug'.
+
**INTEGRITY_CHECK=(**check1 ...**)**::
File integrity checks to use. Multiple checks may be specified; this
affects both generation and checking. The current valid options are:
diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in
index 1c7aacf..184502d 100644
--- a/scripts/libmakepkg/tidy/strip.sh.in
+++ b/scripts/libmakepkg/tidy/strip.sh.in
@@ -37,6 +37,7 @@ build_id() {
strip_file() {
local binary=$1; shift
+ local minidebug_applicable=$1; shift
if check_option "debug" "y"; then
local bid=$(build_id "$binary")
@@ -76,7 +77,51 @@ strip_file() {
fi
fi
+ # Generate minidebuginfo if requested
+ if check_option "minidebug" "y" && [[ $minidebug_applicable == "y" ]]; then
+ # make sure not to operate on the same file twice
+ if ! check_option "debug" "y" && objdump -h "$binary" | grep -q .gnu_debugdata; then
+ return;
+ fi
+ if ! check_option "debug" "y"; then
+ local debug=$(mktemp)
+ objcopy --only-keep-debug "$binary" "$debug"
+ else
+ local debug="$dbgdir/$binary.debug"
+ fi
+ add_minidebug "$binary" "$debug"
+ if ! check_option "debug" "y"; then
+ rm -f "$debug"
+ fi
+ fi
+
strip $@ "$binary"
+
+}
+
+
+# This function is based on the one written for use in RPM by Alexander Larsson.
+# (https://bugzilla.redhat.com/attachment.cgi?id=594198)
+add_minidebug() {
+ local dynsyms=$(mktemp)
+ local funcsyms=$(mktemp)
+ local keep_symbols=$(mktemp)
+ # Extract the dynamic symbols from the main binary, there is no need to also have these
+ LC_ALL=C nm -D "$1" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms"
+ # Extract all function symbols (see https://bugzilla.redhat.com/show_bug.cgi?id=1052415#c11)
+ LC_ALL=C nm "$1" --format=sysv --defined-only | awk -F \| '{ if ($4 ~ "FUNC") print $1 }' | sort > "$funcsyms"
+ # Keep all the function symbols not already in the dynamic symbol table
+ LC_ALL=C comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols"
+ if [[ -s "$keep_symbols" ]]; then
+ local minidebug=$(mktemp)
+ # Copy the full debuginfo, keeping only a minimal set of symbols and removing some unnecessary sections.
+ objcopy --strip-all --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" \
+ "$2" "$minidebug"
+ xz "$minidebug"
+ objcopy --add-section .gnu_debugdata="$minidebug.xz" "$binary"
+ rm -f "$minidebug.xz"
+ fi
+ rm -f "$dynsyms" "$funcsyms" "$keep_symbols"
}
@@ -93,25 +138,30 @@ tidy_strip() {
fi
local binary strip_flags
+ local minidebug_applicable # MiniDebugInfo is only useful with shared libraries and executables
find . -type f -perm -u+w -print0 2>/dev/null | while read -rd '' binary ; do
case "$(file -bi "$binary")" in
*application/x-sharedlib*) # Libraries (.so)
- strip_flags="$STRIP_SHARED";;
+ strip_flags="$STRIP_SHARED"
+ minidebug_applicable="y";;
*application/x-archive*) # Libraries (.a)
- strip_flags="$STRIP_STATIC";;
+ strip_flags="$STRIP_STATIC"
+ minidebug_applicable="n";;
*application/x-object*)
case "$binary" in
*.ko) # Kernel module
- strip_flags="$STRIP_SHARED";;
+ strip_flags="$STRIP_SHARED"
+ minidebug_applicable="n";;
*)
continue;;
esac;;
*application/x-executable*) # Binaries
- strip_flags="$STRIP_BINARIES";;
+ strip_flags="$STRIP_BINARIES"
+ minidebug_applicable="y";;
*)
continue ;;
esac
- strip_file "$binary" ${strip_flags}
+ strip_file "$binary" $minidebug_applicable ${strip_flags}
done
fi
}
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 80b95f4..b6195b5 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -791,7 +791,7 @@ run_function() {
unset CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
fi
- if check_option "debug" "y"; then
+ if check_option "debug" "y" || check_option "minidebug" "y"; then
CFLAGS+=" $DEBUG_CFLAGS"
CXXFLAGS+=" $DEBUG_CXXFLAGS"
fi
--
2.7.0
More information about the pacman-dev
mailing list