[PATCH 2/2] Unwind: demangle symbol names

Masatake YAMATO yamato at redhat.com
Mon Dec 18 04:24:55 UTC 2017


This patch is for demangling c++ symbols appeared in stack trace
with using cplus_demangle function in GNU libiberty library.

This is an example of output of demangled stack trace:

fstat(5, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
 > /usr/lib64/libc-2.25.so(__fxstat64+0x12) [0xffd62]
 > /usr/lib64/libc-2.25.so(_IO_file_doallocate+0x5f) [0x717ff]
 > /usr/lib64/libc-2.25.so(_IO_doallocbuf+0x79) [0x81699]
 > /usr/lib64/libc-2.25.so(_IO_file_overflow+0x198) [0x807b8]
 > /usr/lib64/libc-2.25.so(_IO_file_xsputn+0xbd) [0x7ed5d]
 > /usr/lib64/libc-2.25.so(fwrite_unlocked+0x60) [0x7d800]
 > /usr/lib64/libleveldb.so.1.18(leveldb::EnvWrapper::StartThread+0x3b6) [0x48656]
 > /usr/lib64/libleveldb.so.1.18(leveldb::log::Writer::EmitPhysicalRecord+0x89) [0x28bc9]
 > /usr/lib64/libleveldb.so.1.18(leveldb::log::Writer::AddRecord+0x9e) [0x28d9e]
 > /usr/lib64/libleveldb.so.1.18(leveldb::DBImpl::Write+0x208) [0x1ce18]
 > /usr/lib64/libleveldb.so.1.18(leveldb::DB::Put+0x59) [0x192b9]
 > /usr/lib64/libleveldb.so.1.18(leveldb::DBImpl::Put+0x1d) [0x1931d]
 > /home/yamato/var/leveldb/doc/a.out(main+0x120) [0x1107]
 > /usr/lib64/libc-2.25.so(__libc_start_main+0xea) [0x2088a]
 > /home/yamato/var/leveldb/doc/a.out(_start+0x2a) [0xf3a]

The names of leveldb related symbols are demangled well.

* Makefile.am (libiberty_CPPFLAGS): New macro
  appended to strace_CPPFLAGS if USE_DEMANGLE is defined.
  (libiberty_LDFLAGS): New macro appended to strace_LDFLAGS if
  USE_DEMANGLE is defined.
  (libiberty_LDADD): New macro appended to strace_LIBS if
  USE_DEMANGLE is defined.
* configure.ac : Add --with-libiberty optoin.
  Check libiberty support.
* unwind.c: Include demangle.h.
 (print_stack_frame): Call cplus_demangle.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 Makefile.am  |  5 +++++
 configure.ac | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 unwind.c     | 17 +++++++++++++++++
 3 files changed, 73 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index c04125ec..b5512741 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -333,6 +333,11 @@ strace_SOURCES += unwind.c
 strace_CPPFLAGS += $(libunwind_CPPFLAGS)
 strace_LDFLAGS += $(libunwind_LDFLAGS)
 strace_LDADD += $(libunwind_LIBS)
+if  USE_DEMANGLE
+strace_CPPFLAGS += $(libiberty_CPPFLAGS)
+strace_LDFLAGS += $(libiberty_LDFLAGS)
+strace_LDADD += $(libiberty_LIBS)
+endif
 endif
 
 @CODE_COVERAGE_RULES@
diff --git a/configure.ac b/configure.ac
index 729ef3f7..e2a5d97a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -883,6 +883,57 @@ fi
 AM_CONDITIONAL([USE_LIBUNWIND], [test "x$use_libunwind" = xyes])
 AC_MSG_RESULT([$use_libunwind])
 
+dnl demangling symbols in the stack trace
+AC_ARG_WITH([libiberty],
+	    [AS_HELP_STRING([--with-libiberty],
+			    [use libiberty to demangle symbols in stack trace])],
+	    [case "${withval}" in
+	     yes|no|check) ;;
+	     *) with_libiberty=yes
+		libiberty_CPPFLAGS="-I${withval}/include"
+		libiberty_LDFLAGS="-L${withval}/lib" ;;
+	     esac],
+	    [with_libiberty=check]
+)
+
+use_libiberty=no
+AS_IF([test "x$use_libunwind" = xyes && test "x$with_libiberty" != xno],
+      [saved_CPPFLAGS="$CPPFLAGS"
+       CPPFALGS="$CPPFLAGS $libiberty_CPPFLAGS"
+       AC_CHECK_HEADERS([demangle.h],
+	 [saved_LDFLAGS="$LDFLAGS"
+	  LDFLAGS="$LDFLAGS $libiberty_LDFLAGS"
+	  AC_CHECK_LIB([iberty],[cplus_demangle],
+	    [libiberty_LIBS="-liberty"
+	     use_libiberty=yes
+	    ],
+	    [if test "x$with_libiberty" != xcheck; then
+	       AC_MSG_FAILURE([failed to find cplus_demangle in libiberty])
+	     fi
+	    ]
+	  )
+	  LDFLAGS="$saved_LDFLAGS"
+	 ],
+	 [if test "x$with_libiberty" != xcheck; then
+	      AC_MSG_FAILURE([failed to find demangle.h])
+	  fi
+	 ]
+       )
+       CPPFLAGS="$saved_CPPFLAGS"
+      ]
+)
+
+dnl enable libiberty
+AC_MSG_CHECKING([whether to enable demangling symbols in stack trace])
+if test "x$use_libiberty" = xyes; then
+	AC_DEFINE([USE_DEMANGLE], 1, [Do demangling symbols in stack trace])
+	AC_SUBST(libiberty_LIBS)
+	AC_SUBST(libiberty_LDFLAGS)
+	AC_SUBST(libiberty_CPPFLAGS)
+fi
+AM_CONDITIONAL([USE_DEMANGLE], [test "x$use_libiberty" = xyes])
+AC_MSG_RESULT([$use_libiberty])
+
 if test "$arch" = mips && test "$no_create" != yes; then
 	mkdir -p linux/mips
 	if $srcdir/linux/mips/genstub.sh linux/mips; then
diff --git a/unwind.c b/unwind.c
index c097e875..7168810c 100644
--- a/unwind.c
+++ b/unwind.c
@@ -29,6 +29,10 @@
 #include <limits.h>
 #include <libunwind-ptrace.h>
 
+#ifdef USE_DEMANGLE
+#include <demangle.h>
+#endif
+
 #ifdef _LARGEFILE64_SOURCE
 # ifdef HAVE_FOPEN64
 #  define fopen_for_input fopen64
@@ -325,11 +329,24 @@ print_stack_frame(struct tcb *tcp,
 					&function_offset);
 			true_offset = ip - cur_mmap_cache->start_addr +
 				cur_mmap_cache->mmap_offset;
+
+#ifdef USE_DEMANGLE
+			char *demangled_name = cplus_demangle (*symbol_name, 0);
+#endif
+
 			call_action(data,
 				    cur_mmap_cache->binary_filename,
+#ifdef USE_DEMANGLE
+				    demangled_name? demangled_name: *symbol_name,
+#else
 				    *symbol_name,
+#endif
 				    function_offset,
 				    true_offset);
+#ifdef USE_DEMANGLE
+			free (demangled_name);
+#endif
+
 			return 0;
 		} else if (ip < cur_mmap_cache->start_addr)
 			upper = mid - 1;
-- 
2.14.3





More information about the Strace-devel mailing list