summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-01-20 23:09:26 +0100
committerMark Wielaard <mjw@redhat.com>2014-01-27 15:53:40 +0100
commit531a30acbe175da1f71768e2ffb585c4d45e640b (patch)
tree3e10641f026119f8bec106d7a5510e5f7cf05278
parent247f85869852e5f0fc461c4c9827d1347e75204a (diff)
downloadelfutils-531a30acbe175da1f71768e2ffb585c4d45e640b.tar.gz
stack: Add -d, --debugname. Lookup DWARF debuginfo name for frame address.
Includes test that shows -d matches the function name that corresponds to the actual source line we report with -s for a frame address. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--ChangeLog4
-rw-r--r--NEWS4
-rw-r--r--src/ChangeLog10
-rw-r--r--src/stack.c56
-rw-r--r--tests/ChangeLog9
-rw-r--r--tests/Makefile.am6
-rwxr-xr-xtests/run-stack-d-test.sh112
-rwxr-xr-xtests/testfiledwarfinlines.bz2bin0 -> 4225 bytes
-rw-r--r--tests/testfiledwarfinlines.core.bz2bin0 -> 39713 bytes
9 files changed, 196 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index c3bea171..ad8cd033 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-01-20 Mark Wielaard <mjw@redhat.com>
+
+ * NEWS (Version 0.159): New. Add stack -d.
+
2014-01-03 Mark Wielaard <mjw@redhat.com>
* configure.ac: Set version to 0.158.
diff --git a/NEWS b/NEWS
index 44f1959a..5c865e0b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Version 0.159
+
+stack: New option -d, --debugname to lookup DWARF debuginfo name for frame.
+
Version 0.158
libdwfl: dwfl_core_file_report has new parameter executable.
diff --git a/src/ChangeLog b/src/ChangeLog
index 57be0bb3..143d73cc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,15 @@
2014-01-20 Mark Wielaard <mjw@redhat.com>
+ * stack.c (show_debugname): New static boolean.
+ (die_name): New function.
+ (print_frames): If show_debugname is true set symname to the
+ first function-like DIE with a name in scope for the address in
+ the debuginfo.
+ (parse_opt): Handle '-d'.
+ (main): Add 'd' to options.
+
+2014-01-20 Mark Wielaard <mjw@redhat.com>
+
* addr2line.c (handle_address): Initialize scopes to NULL.
2014-01-17 Roland McGrath <roland@redhat.com>
diff --git a/src/stack.c b/src/stack.c
index 275be08c..ae0ef126 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -28,6 +28,7 @@
#include <fcntl.h>
#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
#include <system.h>
/* Name and version of program. */
@@ -49,6 +50,7 @@ static bool show_one_tid = false;
static bool show_quiet = false;
static bool show_raw = false;
static bool show_modules = false;
+static bool show_debugname = false;
static int maxframes = 2048;
@@ -192,6 +194,23 @@ frame_callback (Dwfl_Frame *state, void *arg)
return DWARF_CB_OK;
}
+static const char*
+die_name (Dwarf_Die *die)
+{
+ Dwarf_Attribute attr;
+ const char *name;
+ name = dwarf_formstring (dwarf_attr_integrate (die,
+ DW_AT_MIPS_linkage_name,
+ &attr)
+ ?: dwarf_attr_integrate (die,
+ DW_AT_linkage_name,
+ &attr));
+ if (name == NULL)
+ name = dwarf_diename (die);
+
+ return name;
+}
+
static void
print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what)
{
@@ -209,7 +228,31 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what)
Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
const char *symname = NULL;
if (mod && ! show_quiet)
- symname = dwfl_module_addrname (mod, pc_adjusted);
+ {
+ if (show_debugname)
+ {
+ Dwarf_Addr bias = 0;
+ Dwarf_Die *cudie = dwfl_module_addrdie (mod, pc_adjusted, &bias);
+ Dwarf_Die *scopes = NULL;
+ int nscopes = dwarf_getscopes (cudie, pc_adjusted - bias,
+ &scopes);
+
+ /* Find the first function-like DIE with a name in scope. */
+ for (int i = 0; symname == NULL && i < nscopes; i++)
+ {
+ Dwarf_Die *scope = &scopes[i];
+ int tag = dwarf_tag (scope);
+ if (tag == DW_TAG_subprogram
+ || tag == DW_TAG_inlined_subroutine
+ || tag == DW_TAG_entry_point)
+ symname = die_name (scope);
+ }
+ free (scopes);
+ }
+
+ if (symname == NULL)
+ symname = dwfl_module_addrname (mod, pc_adjusted);
+ }
int width = get_addr_width (mod);
printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc);
@@ -382,8 +425,12 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
show_activation = true;
break;
+ case 'd':
+ show_debugname = true;
+ break;
+
case 'v':
- show_activation = show_source = show_module = true;
+ show_activation = show_source = show_module = show_debugname = true;
break;
case 'b':
@@ -506,12 +553,15 @@ main (int argc, char **argv)
{ NULL, 0, NULL, 0, N_("Output selection options:"), 0 },
{ "activation", 'a', NULL, 0,
N_("Additionally show frame activation"), 0 },
+ { "debugname", 'd', NULL, 0,
+ N_("Additionally try to lookup DWARF debuginfo name for frame address"),
+ 0 },
{ "module", 'm', NULL, 0,
N_("Additionally show module file information"), 0 },
{ "source", 's', NULL, 0,
N_("Additionally show source file information"), 0 },
{ "verbose", 'v', NULL, 0,
- N_("Show all additional information (activation, module and source)"), 0 },
+ N_("Show all additional information (activation, debugname, module and source)"), 0 },
{ "quiet", 'q', NULL, 0,
N_("Do not resolve address to function symbol name"), 0 },
{ "raw", 'r', NULL, 0,
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 733d8e61..70b05510 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2014-01-20 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am (TESTS): Add run-stack-d-test.sh.
+ (EXTRA_DIST): Add run-stack-d-test.sh, testfiledwarfinlines.bz2
+ testfiledwarfinlines.core.bz2.
+ * run-stack-d-test.sh: New test.
+ * testfiledwarfinlines.bz2: New test file.
+ * testfiledwarfinlines.core.bz2: Likewise.
+
2014-01-16 Mark Wielaard <mjw@redhat.com>
* run-nm-self.sh: Don't use testrun_on_self_quiet but just testrun
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1253574d..35f6e87e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -108,7 +108,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \
run-backtrace-core-i386.sh run-backtrace-core-ppc.sh \
run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
- run-backtrace-demangle.sh
+ run-backtrace-demangle.sh run-stack-d-test.sh
if !BIARCH
export ELFUTILS_DISABLE_BIARCH = 1
@@ -264,7 +264,9 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
run-backtrace-demangle.sh testfile-backtrace-demangle.bz2 \
testfile-backtrace-demangle.cc \
- testfile-backtrace-demangle.core.bz2
+ testfile-backtrace-demangle.core.bz2 \
+ run-stack-d-test.sh \
+ testfiledwarfinlines.bz2 testfiledwarfinlines.core.bz2
if USE_VALGRIND
valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no'
diff --git a/tests/run-stack-d-test.sh b/tests/run-stack-d-test.sh
new file mode 100755
index 00000000..040c2fa9
--- /dev/null
+++ b/tests/run-stack-d-test.sh
@@ -0,0 +1,112 @@
+#! /bin/sh
+# Copyright (C) 2014 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/>.
+
+. $srcdir/test-subr.sh
+
+# // g++ dwarfinlines.cpp -g -o testfiledwarfinlines -O2
+# int
+# fubar (int x)
+# {
+# __asm__ ( "nop" ::: );
+# return 42 / x - 2;
+# }
+#
+# void foobar (int z1, int z2)
+# {
+# __asm__ ( "nop" ::: );
+# int x = z1 + z2;
+# while (z1 + x + 1 != 42)
+# x = fubar (z1 + z2 + x);
+# }
+#
+# void bar (int z)
+# {
+# int a, b;
+# a = b = z / 2;
+# foobar(a, b);
+# }
+#
+# void foo (int x)
+# {
+# if (x > 0)
+# bar(x - 2);
+# }
+#
+# void fu (int y)
+# {
+# __asm__ ( "nop" ::: );
+# foo (y + 1);
+# }
+#
+# int
+# main (int argc, char **argv)
+# {
+# fu (argc);
+# }
+testfiles testfiledwarfinlines testfiledwarfinlines.core
+
+# Depending on whether we are running make check or make installcheck
+# the actual binary name under test might be different. It is used in
+# the error message, which we also try to match.
+if test "$elfutils_testrun" = "installed"; then
+STACKCMD=${bindir}/`program_transform stack`
+else
+STACKCMD=${abs_top_builddir}/src/stack
+fi
+
+# Without -d the top function comes out as fu.
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0 0x00000000004006c8 fu(int)
+#1 0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# But when asking for source we see it is actually on line 6.
+# (Which is in function fubar, not fu).
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -s -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0 0x00000000004006c8 fu(int)
+ /home/mark/src/tests/dwarfinlines.cpp:6
+#1 0x00000000004004c5 main
+ /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# So with --debugname we get the function correct as fubar.
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -d -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0 0x00000000004006c8 fubar
+#1 0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# Which now matches the source line (again 6 of course).
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -s -d -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0 0x00000000004006c8 fubar
+ /home/mark/src/tests/dwarfinlines.cpp:6
+#1 0x00000000004004c5 main
+ /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+exit 0
diff --git a/tests/testfiledwarfinlines.bz2 b/tests/testfiledwarfinlines.bz2
new file mode 100755
index 00000000..db14f816
--- /dev/null
+++ b/tests/testfiledwarfinlines.bz2
Binary files differ
diff --git a/tests/testfiledwarfinlines.core.bz2 b/tests/testfiledwarfinlines.core.bz2
new file mode 100644
index 00000000..2299e1e7
--- /dev/null
+++ b/tests/testfiledwarfinlines.core.bz2
Binary files differ