]> granicus.if.org Git - strace/commitdiff
unwind: demangle symbol names
authorMasatake YAMATO <yamato@redhat.com>
Mon, 18 Dec 2017 04:24:55 +0000 (13:24 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 26 Dec 2017 21:36:49 +0000 (21:36 +0000)
Implement demangling of C++ symbol names in stack trace
using cplus_demangle function from GNU libiberty library.

This is an example demangled stack trace output:

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]

* Makefile.am [USE_DEMANGLE] (strace_CPPFLAGS, strace_LDFLAGS,
libiberty_LDADD): Append libiberty_CPPFLAGS, strace_LDFLAGS, and
libiberty_LIBS, respectively.
* configure.ac: Add --with-libiberty option.  Check cplus_demangle
support in libiberty.
* unwind.c [USE_DEMANGLE]: Include <demangle.h>.
(print_stack_frame) [USE_DEMANGLE]: Use cplus_demangle.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Makefile.am
configure.ac
unwind.c

index 030dc980fb1d5b2075392f31941351027549099f..047327a43036fde0abab77ca439274f7945cee4b 100644 (file)
@@ -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@
index 2bddc6e2844f93940e0f0a68a5e2589a67a1a056..4ee25bbbd274ec6a26a9d89d5e2c4f9e2a5f3690 100644 (file)
@@ -891,6 +891,60 @@ fi
 AM_CONDITIONAL([USE_LIBUNWIND], [test "x$use_libunwind" = xyes])
 AC_MSG_RESULT([$use_libunwind])
 
+dnl demangling symbols in the stack trace
+libiberty_CPPFLAGS=
+libiberty_LDFLAGS=
+libiberty_LIBS=
+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
index d37f016957126913f4add0347cd75ca8a7785678..3a66c3fc0c29a0b4c1515ec68c7e063feb438b66 100644 (file)
--- a/unwind.c
+++ b/unwind.c
 #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
@@ -316,11 +320,23 @@ 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 :
+#endif
                                    *symbol_name,
                                    function_offset,
                                    true_offset);
+#ifdef USE_DEMANGLE
+                       free(demangled_name);
+#endif
+
                        return 0;
                } else if (ip < cur_mmap_cache->start_addr)
                        upper = mid - 1;