Dear Maintainer,
sorry, did attempt to output the build-id unconditionally,
fixed in attached patch version.

Kind regards,
Bernhard
>From 0a4a73d4eeaa45acdbeb6ea8fea878e134cbc11b 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      | 50 ++++++++++++++++++++++++++++++++---------
 2 files changed, 70 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..fd6a232a 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,48 @@ 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)
+  objdumptest=`objdump --version 2>/dev/null`
+  if test $? -eq 0; then
+    echo "\nBuild-IDs:"
+    sort -u "$used_libs" | while read lib; do
+      objdump -s -j .note.gnu.build-id "$lib"
+    done
+  fi
 fi
 rm -f "$segv_output"
+rm -f "$used_libs"
 
 exit $exval
-- 
2.24.0

Reply via email to