summaryrefslogtreecommitdiff
path: root/tools/perf/util
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2023-03-28 16:55:43 -0700
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-04-04 09:39:56 -0300
commit57594454ceb92defaa0707cf29289f0c3c266ede (patch)
tree43d67d121ce11ca1096e42017f7682b56746da55 /tools/perf/util
parent0b02b47e71fa0e006407efd4f647b0e1336a2e8c (diff)
perf symbol: Add command line support for addr2line path
Allow addr2line to be set either on the command line or via the perfconfig file. This doesn't currently work with llvm-addr2line as the addr2line code emits two things: 1) the address to decode, 2) a bogus ',' value. The expectation is the bogus value will generate: ?? ??:0 that terminates the addr2line reading. However, the output from llvm-addr2line is a single line with just the input ',' locking up the addr2line reading that is expecting a second line. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Andres Freund <andres@anarazel.de> Cc: German Gomez <german.gomez@arm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sandipan Das <sandipan.das@amd.com> Cc: Tom Rix <trix@redhat.com> Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20230328235543.1082207-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/annotate.c6
-rw-r--r--tools/perf/util/srcline.c26
-rw-r--r--tools/perf/util/symbol_conf.h1
3 files changed, 23 insertions, 10 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 317c987d3001..f47b5dde66bc 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -3217,6 +3217,12 @@ static int annotation__config(const char *var, const char *value, void *data)
pr_err("Not enough memory for annotate.objdump\n");
return -1;
}
+ } else if (!strcmp(var, "annotate.addr2line")) {
+ symbol_conf.addr2line_path = strdup(value);
+ if (!symbol_conf.addr2line_path) {
+ pr_err("Not enough memory for annotate.addr2line\n");
+ return -1;
+ }
} else if (!strcmp(var, "annotate.demangle")) {
symbol_conf.demangle = perf_config_bool("demangle", value);
} else if (!strcmp(var, "annotate.demangle_kernel")) {
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 33321867416b..f0a96a834e4b 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -414,9 +414,14 @@ static void addr2line_subprocess_cleanup(struct a2l_subprocess *a2l)
free(a2l);
}
-static struct a2l_subprocess *addr2line_subprocess_init(const char *path)
-{
- const char *argv[] = { "addr2line", "-e", path, "-i", "-f", NULL };
+static struct a2l_subprocess *addr2line_subprocess_init(const char *addr2line_path,
+ const char *binary_path)
+{
+ const char *argv[] = {
+ addr2line_path ?: "addr2line",
+ "-e", binary_path,
+ "-i", "-f", NULL
+ };
struct a2l_subprocess *a2l = zalloc(sizeof(*a2l));
int start_command_status = 0;
@@ -436,21 +441,22 @@ static struct a2l_subprocess *addr2line_subprocess_init(const char *path)
a2l->addr2line.argv = NULL; /* it's not used after start_command; avoid dangling pointers */
if (start_command_status != 0) {
- pr_warning("could not start addr2line for %s: start_command return code %d\n",
- path,
- start_command_status);
+ pr_warning("could not start addr2line (%s) for %s: start_command return code %d\n",
+ addr2line_path, binary_path, start_command_status);
goto out;
}
a2l->to_child = fdopen(a2l->addr2line.in, "w");
if (a2l->to_child == NULL) {
- pr_warning("could not open write-stream to addr2line of %s\n", path);
+ pr_warning("could not open write-stream to addr2line (%s) of %s\n",
+ addr2line_path, binary_path);
goto out;
}
a2l->from_child = fdopen(a2l->addr2line.out, "r");
if (a2l->from_child == NULL) {
- pr_warning("could not open read-stream from addr2line of %s\n", path);
+ pr_warning("could not open read-stream from addr2line (%s) of %s\n",
+ addr2line_path, binary_path);
goto out;
}
@@ -490,7 +496,6 @@ static int read_addr2line_record(struct a2l_subprocess *a2l,
if (getline(&line, &line_len, a2l->from_child) < 0 || !line_len)
goto error;
-
if (function != NULL)
*function = strdup(strim(line));
@@ -553,7 +558,8 @@ static int addr2line(const char *dso_name, u64 addr,
if (!filename__has_section(dso_name, ".debug_line"))
goto out;
- dso->a2l = addr2line_subprocess_init(dso_name);
+ dso->a2l = addr2line_subprocess_init(symbol_conf.addr2line_path,
+ dso_name);
a2l = dso->a2l;
}
diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h
index bc3d046fbb63..5accd8e69ad2 100644
--- a/tools/perf/util/symbol_conf.h
+++ b/tools/perf/util/symbol_conf.h
@@ -61,6 +61,7 @@ struct symbol_conf {
*sym_list_str,
*col_width_list_str,
*bt_stop_list_str;
+ char *addr2line_path;
unsigned long time_quantum;
struct strlist *dso_list,
*comm_list,