addr2line: Add --pretty-print option to show all information on one line.

This adds an option --pretty-print to eu-addr2line to show all information
on one line and all inlines on a line of their own. This mimics the same
option from binutils addr2line, but without the short option variant -p.
Since we already use -p to select the process.

Example output:

eu-addr2line --pretty-print -s -i -f -C -p$(pidof firefox) 0x00007f368c6f8915
mozilla::ReentrantMonitor::Wait(unsigned int) at ReentrantMonitor.h:92
 (inlined by) mozilla::ReentrantMonitorAutoEnter::Wait(unsigned int) at ReentrantMonitor.h:190

A couple of tests were added to check the output matches that of
binutils addr2line.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
This commit is contained in:
Mark Wielaard
2015-05-20 14:09:46 +02:00
parent cd2da6c37b
commit b23a5b2dda
6 changed files with 81 additions and 11 deletions
+1
View File
@@ -6,6 +6,7 @@ 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.
New option --pretty-print to print all information on one line.
Version 0.161
+10
View File
@@ -1,3 +1,13 @@
2015-05-20 Mark Wielaard <mjw@redhat.com>
* addr2line.c (OPT_PRETTY): New constant define.
(argp_option): Add "pretty-print".
(pretty): New static bool.
(parse_opt): Set pretty.
(print_dwarf_function): Adjust output when pretty is set.
(print_addrsym): Likewise.
(handle_address): Likewise.
2015-05-20 Mark Wielaard <mjw@redhat.com>
* Makefile.am (addr2line_LDADD): Add demanglelib.
+36 -11
View File
@@ -50,6 +50,7 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
/* Values for the parameters which have no short form. */
#define OPT_DEMANGLER 0x100
#define OPT_PRETTY 0x101 /* 'p' is already used to select the process. */
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
@@ -72,6 +73,8 @@ static const struct argp_option options[] =
0 },
{ "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL,
N_("Show demangled symbols (ARG is always ignored)"), 0 },
{ "pretty-print", OPT_PRETTY, NULL, 0,
N_("Print all information on one line, and indent inlines"), 0 },
{ NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
/* Unsupported options. */
@@ -132,6 +135,9 @@ static bool show_inlines;
/* True if all names need to be demangled. */
static bool demangle;
/* True if all information should be printed on one line. */
static bool pretty;
#ifdef USE_DEMANGLE
static size_t demangle_buffer_len = 0;
static char *demangle_buffer = NULL;
@@ -269,6 +275,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
show_inlines = true;
break;
case OPT_PRETTY:
pretty = true;
break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -328,7 +338,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
const char *name = get_diename (&scopes[i]);
if (name == NULL)
return false;
puts (symname (name));
printf ("%s%c", symname (name), pretty ? ' ' : '\n');
return true;
}
@@ -337,7 +347,16 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
const char *name = get_diename (&scopes[i]);
if (name == NULL)
return false;
printf ("%s inlined", symname (name));
/* When using --pretty-print we only show inlines on their
own line. Just print the first subroutine name. */
if (pretty)
{
printf ("%s ", symname (name));
return true;
}
else
printf ("%s inlined", symname (name));
Dwarf_Files *files;
if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
@@ -412,9 +431,9 @@ print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
if (i >= 0)
name = dwfl_module_relocation_info (mod, i, NULL);
if (name == NULL)
puts ("??");
printf ("??%c", pretty ? ' ': '\n');
else
printf ("(%s)+%#" PRIx64 "\n", name, addr);
printf ("(%s)+%#" PRIx64 "%c", name, addr, pretty ? ' ' : '\n');
}
else
{
@@ -443,7 +462,7 @@ print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
}
}
}
puts ("");
printf ("%c", pretty ? ' ' : '\n');
}
}
@@ -645,7 +664,7 @@ handle_address (const char *string, Dwfl *dwfl)
if (print_addresses)
{
int width = get_addr_width (mod);
printf ("0x%.*" PRIx64 "\n", width, addr);
printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n");
}
if (show_functions)
@@ -655,16 +674,17 @@ handle_address (const char *string, Dwfl *dwfl)
if (! print_dwarf_function (mod, addr) && !show_symbols)
{
const char *name = dwfl_module_addrname (mod, addr);
if (name != NULL)
puts (symname (name));
else
puts ("??");
name = name != NULL ? symname (name) : "??";
printf ("%s%c", name, pretty ? ' ' : '\n');
}
}
if (show_symbols)
print_addrsym (mod, addr);
if ((show_functions || show_symbols) && pretty)
printf ("at ");
Dwfl_Line *line = dwfl_module_getsrc (mod, addr);
const char *src;
@@ -741,6 +761,9 @@ handle_address (const char *string, Dwfl *dwfl)
if (dwarf_tag (die) != DW_TAG_inlined_subroutine)
continue;
if (pretty)
printf (" (inlined by) ");
if (show_functions)
{
/* Search for the parent inline or function. It
@@ -754,7 +777,9 @@ handle_address (const char *string, Dwfl *dwfl)
|| tag == DW_TAG_entry_point
|| tag == DW_TAG_subprogram)
{
puts (symname (get_diename (parent)));
printf ("%s%s",
symname (get_diename (parent)),
pretty ? " at " : "\n");
break;
}
}
+5
View File
@@ -1,3 +1,8 @@
2015-05-20 Mark Wielaard <mjw@redhat.com>
* run-addr2line-i-test.sh: Add pretty test.
* run-addr2line-test.sh: Likewise.
2015-05-20 Mark Wielaard <mjw@redhat.com>
* run-addr2line-i-demangle-test.sh: New test.
+23
View File
@@ -197,4 +197,27 @@ _Z2fuv
/tmp/x.cpp:33
EOF
# All together now (plus function names and addresses and pretty)
testrun_compare ${abs_top_builddir}/src/addr2line --pretty-print -a -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
0x00000000000005a0: foobar at /tmp/x.cpp:5
0x00000000000005a1: foobar at /tmp/x.cpp:6
0x00000000000005b0: fubar at /tmp/x.cpp:10
0x00000000000005b1: fubar at /tmp/x.cpp:11
0x00000000000005c0: foobar at /tmp/x.cpp:5
(inlined by) bar at /tmp/x.cpp:15
0x00000000000005d0: fubar at /tmp/x.cpp:10
(inlined by) baz at /tmp/x.cpp:20
0x00000000000005e0: foobar at /tmp/x.cpp:5
(inlined by) bar at /tmp/x.cpp:15
(inlined by) _Z3foov at /tmp/x.cpp:25
0x00000000000005e1: fubar at /tmp/x.cpp:10
(inlined by) baz at /tmp/x.cpp:20
(inlined by) _Z3foov at /tmp/x.cpp:26
0x00000000000005f0: _Z2fuv at /tmp/x.cpp:31
0x00000000000005f1: fubar at /tmp/x.cpp:10
(inlined by) _Z2fuv at /tmp/x.cpp:32
0x00000000000005f2: foobar at /tmp/x.cpp:5
(inlined by) _Z2fuv at /tmp/x.cpp:33
EOF
exit 0
+6
View File
@@ -107,4 +107,10 @@ echo "# Everything from stdin (with newlines) with addresses."
cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -a -f -e testfile > stdin.nl.out || exit 1
cmp good.addr.out stdin.nl.out || exit 1
echo "# Pretty with functions and addresses."
testrun_compare ${abs_top_builddir}/src/addr2line --pretty -a -f -e testfile 0x08048468 0x0804845c << EOF
0x08048468: foo at /home/drepper/gnu/new-bu/build/ttt/f.c:3
0x0804845c: bar at /home/drepper/gnu/new-bu/build/ttt/b.c:4
EOF
exit 0