From: Masatake YAMATO Date: Mon, 18 Dec 2017 04:24:55 +0000 (+0900) Subject: unwind: demangle symbol names X-Git-Tag: v4.21~236 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9c8e8a5b6fd9e1420a9f8c88633fedee281f071;p=strace unwind: demangle symbol names 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 . (print_stack_frame) [USE_DEMANGLE]: Use cplus_demangle. Signed-off-by: Masatake YAMATO --- diff --git a/Makefile.am b/Makefile.am index 030dc980..047327a4 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 2bddc6e2..4ee25bbb 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/unwind.c b/unwind.c index d37f0169..3a66c3fc 100644 --- a/unwind.c +++ b/unwind.c @@ -29,6 +29,10 @@ #include #include +#ifdef USE_DEMANGLE +# include +#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;