diff options
| author | Mark Wielaard <[email protected]> | 2015-05-20 11:52:27 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2015-05-27 17:17:51 +0200 |
| commit | cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ec (patch) | |
| tree | 0ffba17e8bcfc5de4372ec5f53690a5679d3fe77 | |
| parent | 70a504d1e19fe14cf34ab3e7a0179aa421f548e0 (diff) | |
addr2line: Add demangler support.
Makes the -C, --demangle option visible and implements it (ignoring the
demangle style argument). Adds a new test with sample output.
Signed-off-by: Mark Wielaard <[email protected]>
| -rw-r--r-- | NEWS | 1 | ||||
| -rw-r--r-- | src/ChangeLog | 15 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/addr2line.c | 48 | ||||
| -rw-r--r-- | tests/ChangeLog | 6 | ||||
| -rw-r--r-- | tests/Makefile.am | 2 | ||||
| -rwxr-xr-x | tests/run-addr2line-i-demangle-test.sh | 69 |
7 files changed, 136 insertions, 7 deletions
@@ -5,6 +5,7 @@ libdw: Install new header elfutils/known-dwarf.h. addr2line: Input addresses are now always interpreted as hexadecimal numbers, never as octal or decimal numbers. New option -a, --addresses to print address before each entry. + New option -C, --demangle to show demangled symbols. Version 0.161 diff --git a/src/ChangeLog b/src/ChangeLog index 127e6013..fe6f6f16 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,20 @@ 2015-05-20 Mark Wielaard <[email protected]> + * Makefile.am (addr2line_LDADD): Add demanglelib. + * addr2line.c (argp_option): Move demangle under output format. + (demangle): New static bool. + (demangle_buffer_len): New static size_t. + (demangle_buffer): New static char *. + (main): free demangle_buffer. + (parse_opt): Set demangle. + (symname): New static function. + (get_diename): Use symname. + (print_dwarf_function): Likewise. + (print_addrsym): Likewise. + (handle_address): Likewise. + +2015-05-20 Mark Wielaard <[email protected]> + * addr2line.c (argp_option): Add "addresses", 'a'. (print_addresses): New static bool. (parse_opt): Set print_addresses. diff --git a/src/Makefile.am b/src/Makefile.am index ab5364fe..58cbe764 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,7 +102,7 @@ endif ld_LDFLAGS = -rdynamic elflint_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl findtextrel_LDADD = $(libdw) $(libelf) $(argp_LDADD) -addr2line_LDADD = $(libdw) $(libelf) $(argp_LDADD) +addr2line_LDADD = $(libdw) $(libelf) $(argp_LDADD) $(demanglelib) elfcmp_LDADD = $(libebl) $(libelf) $(argp_LDADD) -ldl objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) diff --git a/src/addr2line.c b/src/addr2line.c index 720a087e..786afd34 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -70,11 +70,12 @@ static const struct argp_option options[] = { "inlines", 'i', NULL, 0, N_("Show all source locations that caused inline expansion of subroutines at the address."), 0 }, + { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL, + N_("Show demangled symbols (ARG is always ignored)"), 0 }, { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, /* Unsupported options. */ { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 }, - { "demangle", 'C', "ARG", OPTION_HIDDEN | OPTION_ARG_OPTIONAL, NULL, 0 }, { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; @@ -128,6 +129,13 @@ static const char *just_section; /* True if all inlined subroutines of the current address should be shown. */ static bool show_inlines; +/* True if all names need to be demangled. */ +static bool demangle; + +#ifdef USE_DEMANGLE +static size_t demangle_buffer_len = 0; +static char *demangle_buffer = NULL; +#endif int main (int argc, char *argv[]) @@ -185,6 +193,11 @@ main (int argc, char *argv[]) } dwfl_end (dwfl); + +#ifdef USE_DEMANGLE + free (demangle_buffer); +#endif + return result; } @@ -220,7 +233,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'b': case 'C': case OPT_DEMANGLER: - /* Ignored for compatibility. */ + demangle = true; break; case 's': @@ -262,6 +275,22 @@ parse_opt (int key, char *arg, struct argp_state *state) return 0; } +static const char * +symname (const char *name) +{ +#ifdef USE_DEMANGLE + // Require GNU v3 ABI by the "_Z" prefix. + if (demangle && name[0] == '_' && name[1] == 'Z') + { + int status = -1; + char *dsymname = __cxa_demangle (name, demangle_buffer, + &demangle_buffer_len, &status); + if (status == 0) + name = demangle_buffer = dsymname; + } +#endif + return name; +} static const char * get_diename (Dwarf_Die *die) @@ -299,7 +328,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) const char *name = get_diename (&scopes[i]); if (name == NULL) return false; - puts (name); + puts (symname (name)); return true; } @@ -308,7 +337,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) const char *name = get_diename (&scopes[i]); if (name == NULL) return false; - printf ("%s inlined", name); + printf ("%s inlined", symname (name)); Dwarf_Files *files; if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) @@ -389,6 +418,7 @@ print_addrsym (Dwfl_Module *mod, GElf_Addr addr) } else { + name = symname (name); if (off == 0) printf ("%s", name); else @@ -623,7 +653,13 @@ handle_address (const char *string, Dwfl *dwfl) /* First determine the function name. Use the DWARF information if possible. */ if (! print_dwarf_function (mod, addr) && !show_symbols) - puts (dwfl_module_addrname (mod, addr) ?: "??"); + { + const char *name = dwfl_module_addrname (mod, addr); + if (name != NULL) + puts (symname (name)); + else + puts ("??"); + } } if (show_symbols) @@ -718,7 +754,7 @@ handle_address (const char *string, Dwfl *dwfl) || tag == DW_TAG_entry_point || tag == DW_TAG_subprogram) { - puts (get_diename (parent)); + puts (symname (get_diename (parent))); break; } } diff --git a/tests/ChangeLog b/tests/ChangeLog index d3a0e4b0..30ed5f59 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,11 @@ 2015-05-20 Mark Wielaard <[email protected]> + * run-addr2line-i-demangle-test.sh: New test. + * Makefile.am (TESTS): Add run-addr2line-i-demangle-test.sh. + (EXTRA_DIST): Likewise. + +2015-05-20 Mark Wielaard <[email protected]> + * run-addr2line-test.sh: Add -a test variants. * run-addr2line-i-test.sh: Likewise. diff --git a/tests/Makefile.am b/tests/Makefile.am index fdbf5bf2..55241c7d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -104,6 +104,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-readelf-mixed-corenote.sh run-dwfllines.sh \ run-dwfl-report-elf-align.sh run-addr2line-test.sh \ run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \ + run-addr2line-i-demangle-test.sh \ run-varlocs.sh run-funcretval.sh \ run-backtrace-native.sh run-backtrace-data.sh run-backtrace-dwarf.sh \ run-backtrace-native-biarch.sh run-backtrace-native-core.sh \ @@ -254,6 +255,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ test-core.exec.bz2 run-addr2line-test.sh \ run-addr2line-i-test.sh testfile-inlines.bz2 \ run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ + run-addr2line-i-demangle-test.sh \ testfileppc32.bz2 testfileppc64.bz2 \ testfiles390.bz2 testfiles390x.bz2 \ testfilearm.bz2 testfileaarch64.bz2 \ diff --git a/tests/run-addr2line-i-demangle-test.sh b/tests/run-addr2line-i-demangle-test.sh new file mode 100755 index 00000000..e709acfa --- /dev/null +++ b/tests/run-addr2line-i-demangle-test.sh @@ -0,0 +1,69 @@ +#! /bin/sh +# Copyright (C) 2015 Red Hat, Inc. +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +if test -n "$ELFUTILS_DISABLE_DEMANGLE"; then + exit 77 +fi + +. $srcdir/test-subr.sh + +# See run-addr2line-i-test.sh for how to generate test files. +testfiles testfile-inlines + +# All together now plus (demangled) function names. +testrun_compare ${abs_top_builddir}/src/addr2line -C -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF +foobar +/tmp/x.cpp:5 +foobar +/tmp/x.cpp:6 +fubar +/tmp/x.cpp:10 +fubar +/tmp/x.cpp:11 +foobar inlined at /tmp/x.cpp:15 in bar() +/tmp/x.cpp:5 +bar +/tmp/x.cpp:15 +fubar inlined at /tmp/x.cpp:20 in baz() +/tmp/x.cpp:10 +baz +/tmp/x.cpp:20 +foobar inlined at /tmp/x.cpp:15 in foo() +/tmp/x.cpp:5 +bar +/tmp/x.cpp:15 +foo() +/tmp/x.cpp:25 +fubar inlined at /tmp/x.cpp:20 in foo() +/tmp/x.cpp:10 +baz +/tmp/x.cpp:20 +foo() +/tmp/x.cpp:26 +fu() +/tmp/x.cpp:31 +fubar inlined at /tmp/x.cpp:32 in fu() +/tmp/x.cpp:10 +fu() +/tmp/x.cpp:32 +foobar inlined at /tmp/x.cpp:33 in fu() +/tmp/x.cpp:5 +fu() +/tmp/x.cpp:33 +EOF + +exit 0 |
