]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
addr2line: Add --pretty-print option to show all information on one line.
authorMark Wielaard <mjw@redhat.com>
Wed, 20 May 2015 12:09:46 +0000 (14:09 +0200)
committerMark Wielaard <mjw@redhat.com>
Wed, 27 May 2015 15:17:51 +0000 (17:17 +0200)
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>
NEWS
src/ChangeLog
src/addr2line.c
tests/ChangeLog
tests/run-addr2line-i-test.sh
tests/run-addr2line-test.sh

diff --git a/NEWS b/NEWS
index 6304d88d0094fee24c25f26d4e8fa55a24b265a8..6f7c4010e20d1d606a72c1fe4248603e955bed1a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
 
index fe6f6f16e20dac17589253b13309d42c2b148d00..c93d54d14782b0ec95831ca97586448f5f699f61 100644 (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.
index 786afd344c464f239322878376467c3d597b6473..fc2ff284f75177e6371146e903ba2e8734af7589 100644 (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;
                                }
                            }
index 30ed5f590e401bb8f5119ef8c06d216aee5e8d5c..94ee1f7d36382cfbe2411d22b674abc0fa6d7531 100644 (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.
index e62aa201c40ff151f200779d99eb6d300fa37b9f..d08f3cba5ba9d906127d4f25931e0d2d6165f9c4 100755 (executable)
@@ -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
index 8d0606443810d50529af3ee37c908542f299c5b4..1079c3e35ba7590c1db3b93daba7190a68b6b6ba 100755 (executable)
@@ -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