Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1566627
| From | Arnaldo Carvalho de Melo <acme@kernel.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 01/23] perf unwind: Fix looking up dwarf unwind stack info |
| Date | 2017-01-25 15:00 +0100 |
| Message-ID | <t3whe-2sl-71@gated-at.bofh.it> (permalink) |
| References | <t3whb-2sl-5@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
From: Matija Glavinic Pecotic <matija.glavinic-pecotic.ext@nokia.com>
Using perf with call graph method dwarf fails to provide backtrace
support for stripped binary even though .gnu_debuglink points to *.dbg
flavor with properly populated debug symbols.
Problem is reproduced on ARM (v7, v8), kernels 3.14.y, 4.4.y and
4.10.rc3. Perf is configured with libunwind, and unwind dwarf support
[1]. Test code (stress_bt.c) can be found on [2].
Running (explicitly disable other unwinding methods):
$ gcc -g -o stress_bt -fomit-frame-pointer -fno-unwind-tables \
-fno-asynchronous-unwind-tables stress_bt.c
$ perf record -N --call-graph dwarf ./stress_bt
$ perf report
results in properly generated call graph. Stripping the binary and running
it results with missing call graph. Expected result is to have call graph:
$ gcc -g -o stress_bt -fomit-frame-pointer -fno-unwind-tables \
-fno-asynchronous-unwind-tables stress_bt.c
$ objcopy --only-keep-debug stress_bt stress_bt.dbg
$ objcopy --strip-debug stress_bt
$ objcopy --add-gnu-debuglink=stress_bt.dbg stress_bt
$ perf record -N --call-graph dwarf ./stress_bt
$ perf report
Problem is that perf doesn't try to read symbols pointed by gnu
debuglink. Patch adds checking, and reading of the symbols from
debuglink and symsrc. Order of the check is to first check within dso,
then check whether symsrc is defined and try to read from it. Finally,
debuglink is checked. Default locations of debug files are discussed in
[3] and [4]. Comments on RFC are on [5].
[1] https://wiki.linaro.org/LEG/Engineering/TOOLS/perf-callstack-unwinding
[2] [1]#Backtrace_stress_application
[3] https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
[4] https://sourceware.org/binutils/docs/binutils/objcopy.html
[5] https://lkml.org/lkml/2016/8/22/473
Signed-off-by: Matija Glavinic Pecotic <matija.glavinic-pecotic.ext@nokia.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/d309d40a-463f-482b-68e1-1465326efdc1@nokia.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/dso.c | 48 +++++++++++++++++++++-------
tools/perf/util/unwind-libunwind-local.c | 54 +++++++++++++++++++++++++++++---
2 files changed, 86 insertions(+), 16 deletions(-)
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index d2c6cdd9d42b..28d41e709128 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -9,6 +9,13 @@
#include "debug.h"
#include "vdso.h"
+static const char * const debuglink_paths[] = {
+ "%.0s%s",
+ "%s/%s",
+ "%s/.debug/%s",
+ "/usr/lib/debug%s/%s"
+};
+
char dso__symtab_origin(const struct dso *dso)
{
static const char origin[] = {
@@ -44,24 +51,43 @@ int dso__read_binary_type_filename(const struct dso *dso,
size_t len;
switch (type) {
- case DSO_BINARY_TYPE__DEBUGLINK: {
- char *debuglink;
+ case DSO_BINARY_TYPE__DEBUGLINK:
+ {
+ const char *last_slash;
+ char dso_dir[PATH_MAX];
+ char symfile[PATH_MAX];
+ unsigned int i;
len = __symbol__join_symfs(filename, size, dso->long_name);
- debuglink = filename + len;
- while (debuglink != filename && *debuglink != '/')
- debuglink--;
- if (*debuglink == '/')
- debuglink++;
+ last_slash = filename + len;
+ while (last_slash != filename && *last_slash != '/')
+ last_slash--;
- ret = -1;
- if (!is_regular_file(filename))
+ strncpy(dso_dir, filename, last_slash - filename);
+ dso_dir[last_slash-filename] = '\0';
+
+ if (!is_regular_file(filename)) {
+ ret = -1;
+ break;
+ }
+
+ ret = filename__read_debuglink(filename, symfile, PATH_MAX);
+ if (ret)
break;
- ret = filename__read_debuglink(filename, debuglink,
- size - (debuglink - filename));
+ /* Check predefined locations where debug file might reside */
+ ret = -1;
+ for (i = 0; i < ARRAY_SIZE(debuglink_paths); i++) {
+ snprintf(filename, size,
+ debuglink_paths[i], dso_dir, symfile);
+ if (is_regular_file(filename)) {
+ ret = 0;
+ break;
+ }
}
+
break;
+ }
case DSO_BINARY_TYPE__BUILD_ID_CACHE:
if (dso__build_id_filename(dso, filename, size) == NULL)
ret = -1;
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 6fec84dff3f7..bfb9b7987692 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -35,6 +35,7 @@
#include "util.h"
#include "debug.h"
#include "asm/bug.h"
+#include "dso.h"
extern int
UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -297,15 +298,58 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
int fd;
u64 ofs = dso->data.debug_frame_offset;
+ /* debug_frame can reside in:
+ * - dso
+ * - debug pointed by symsrc_filename
+ * - gnu_debuglink, which doesn't necessary
+ * has to be pointed by symsrc_filename
+ */
if (ofs == 0) {
fd = dso__data_get_fd(dso, machine);
- if (fd < 0)
- return -EINVAL;
+ if (fd >= 0) {
+ ofs = elf_section_offset(fd, ".debug_frame");
+ dso__data_put_fd(dso);
+ }
+
+ if (ofs <= 0) {
+ fd = open(dso->symsrc_filename, O_RDONLY);
+ if (fd >= 0) {
+ ofs = elf_section_offset(fd, ".debug_frame");
+ close(fd);
+ }
+ }
+
+ if (ofs <= 0) {
+ char *debuglink = malloc(PATH_MAX);
+ int ret = 0;
+
+ ret = dso__read_binary_type_filename(
+ dso, DSO_BINARY_TYPE__DEBUGLINK,
+ machine->root_dir, debuglink, PATH_MAX);
+ if (!ret) {
+ fd = open(debuglink, O_RDONLY);
+ if (fd >= 0) {
+ ofs = elf_section_offset(fd,
+ ".debug_frame");
+ close(fd);
+ }
+ }
+ if (ofs > 0) {
+ if (dso->symsrc_filename != NULL) {
+ pr_warning(
+ "%s: overwrite symsrc(%s,%s)\n",
+ __func__,
+ dso->symsrc_filename,
+ debuglink);
+ free(dso->symsrc_filename);
+ }
+ dso->symsrc_filename = debuglink;
+ } else {
+ free(debuglink);
+ }
+ }
- /* Check the .debug_frame section for unwinding info */
- ofs = elf_section_offset(fd, ".debug_frame");
dso->data.debug_frame_offset = ofs;
- dso__data_put_fd(dso);
}
*offset = ofs;
--
2.9.3
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[GIT PULL 00/23] perf/core improvements and fixes Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 19/23] perf tools: Propagate perf_config() errors Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 15/23] tools lib bpf: Define prog_type fns with macro Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 10/23] perf script: Add "brstackasm" output for branch stacks Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 11/23] perf probe: Fix wrong register name for arm64 Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 09/23] perf script: Add support for printing assembler Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 18/23] perf scripting perl: Do not die() when not founding event for a type Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 21/23] perf util: Add more debug message on failure path Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 08/23] perf tools: Add disassembler for x86 using the XED library Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 14/23] tools lib bpf: Fix map offsets in relocation Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 02/23] perf hists browser: Put hist_entry folding logic into single function Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 22/23] perf ftrace: Introduce new 'ftrace' tool Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 01/23] perf unwind: Fix looking up dwarf unwind stack info Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 13/23] perf probe: Delete an unnecessary assignment in try_to_find_absolute_address() Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 23/23] perf ftrace: Make 'function_graph' be the default tracer Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 04/23] perf c2c report: Display Total records column in offset view Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100 [PATCH 06/23] perf tools: Add probing for the XED disassembler library Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-25 15:00 +0100
csiph-web