Dear Maintainer, while I was at it, I attempted to change the output to deliver the before mentioned information for addr2line too.
Attached is a improved patch, that would now output following: Backtrace: [0x55f317f9175b] main at /usr/share/doc/libsoxr-dev/examples/3-options-input-fn.c:79 (discriminator 4) /tmp/tmp.sSrfzsTKpn/3-options-input-fn(+0x175b) [0x7fd67920fbbb] __libc_start_main at /root/source/glibc/try1/glibc-2.29/csu/../csu/libc-start.c:342 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xeb,+0x26bbb) [0x55f317f911ba] _start at ??:? /tmp/tmp.sSrfzsTKpn/3-options-input-fn(+0x11ba) At the end there is another small change to add the build-ids of the in the backtrace involved binaries to the output. Kind regards, Bernhard
>From cb1fdbd4e5a7fbeb1de27b72a7945a0b4789d251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Wed, 11 Dec 2019 19:56:39 +0100 Subject: Make catchsegv work again after format changed and add build-ids. https://sourceware.org/bugzilla/show_bug.cgi?id=21830 --- debug/backtracesymsfd.c | 32 +++++++++++++++++++++++++- debug/catchsegv.sh | 51 ++++++++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/debug/backtracesymsfd.c b/debug/backtracesymsfd.c index 5751d62f..9bc058fb 100644 --- a/debug/backtracesymsfd.c +++ b/debug/backtracesymsfd.c @@ -35,13 +35,14 @@ void __backtrace_symbols_fd (void *const *array, int size, int fd) { - struct iovec iov[9]; + struct iovec iov[12]; int cnt; for (cnt = 0; cnt < size; ++cnt) { char buf[WORD_WIDTH]; char buf2[WORD_WIDTH]; + char buf3[WORD_WIDTH]; Dl_info info; struct link_map *map; size_t last = 0; @@ -96,6 +97,35 @@ __backtrace_symbols_fd (void *const *array, int size, int fd) - (char *) iov[last].iov_base); ++last; + /* Even when we have a symbol name, print the file offset to + make processing in addr2line possible. */ + if (info.dli_sname != NULL) + { + iov[last].iov_base = (void *) ","; + iov[last].iov_len = 1; + ++last; + + if (array[cnt] >= (void *) map->l_addr) + { + iov[last].iov_base = (void *) "+0x"; + diff = array[cnt] - (void *) map->l_addr; + } + else + { + iov[last].iov_base = (void *) "-0x"; + diff = (void *) map->l_addr - array[cnt]; + } + iov[last].iov_len = 3; + ++last; + + iov[last].iov_base = _itoa_word ((unsigned long int) diff, + &buf3[WORD_WIDTH], 16, 0); + iov[last].iov_len = (&buf3[WORD_WIDTH] + - (char *) iov[last].iov_base); + ++last; + + } + iov[last].iov_base = (void *) ")"; iov[last].iov_len = 1; ++last; diff --git a/debug/catchsegv.sh b/debug/catchsegv.sh index 245c100f..8d8a38f0 100755 --- a/debug/catchsegv.sh +++ b/debug/catchsegv.sh @@ -52,6 +52,7 @@ Written by Ulrich Drepper.' fi segv_output=`mktemp ${TMPDIR:-/tmp}/segv_output.XXXXXX` || exit +used_libs=`mktemp ${TMPDIR:-/tmp}/used_libs.XXXXXX` || exit # Redirect stderr to avoid termination message from shell. (exec 3>&2 2>/dev/null @@ -87,21 +88,49 @@ if test -s "$segv_output"; then sed '/Backtrace/q' "$segv_output" sed '1,/Backtrace/d' "$segv_output" | (while read line; do - line=`echo $line | sed "s@^$prog\\(\\[.*\\)@\1@"` case "$line" in - \[*) addr=`echo "$line" | sed 's/^\[\(.*\)\]$/\1/'` - complete=`addr2line -f -e "$prog" $addr 2>/dev/null` - if test $? -eq 0; then - echo "`echo "$complete"|sed 'N;s/\(.*\)\n\(.*\)/\2(\1)/;'`$line" - else - echo "$line" - fi - ;; - *) echo "$line" - ;; + *\(*\)\[*\]) + lib=`echo $line | sed "s@^\(.*\)(\(.*\))\[\(.*\)\]\\$@\1@"` + offs=`echo $line | sed "s@^\(.*\)(\(.*\))\[\(.*\)\]\\$@\2@"` + addr=`echo $line | sed "s@^\(.*\)(\(.*\))\[\(.*\)\]\\$@\3@"` + func="" + case "$offs" in + *,*) func=`echo $offs | sed "s@\(.*\),\(.*\)\\$@\1,@"` + offs=`echo $offs | sed "s@\(.*\),\(.*\)\\$@\2@"` + ;; + esac + case "$offs" in + +*) case "$prog" in + */$lib) + lib="$prog" + ;; + esac + complete=`addr2line -p -i -f -e "$lib" $offs 2>/dev/null` + if test $? -eq 0; then + echo " [$addr] $complete $lib($func$offs)" + else + echo " $line" + fi + ;; + *) echo " $line" + ;; + esac + echo "$lib" >> "$used_libs" + ;; + *) echo "$line" + ;; esac done) fi rm -f "$segv_output" +objdumptest=`objdump --version 2>/dev/null` +if test $? -eq 0; then + echo "\nBuild-IDs:" + sort -u /tmp/used_libs.kUDu9V | while read lib; do + objdump -s -j .note.gnu.build-id "$lib" + done +fi +rm -f "$used_libs" + exit $exval -- 2.24.0