summaryrefslogtreecommitdiff
path: root/tools/perf/util/srcline.c
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2023-06-07 23:18:12 -0700
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-06-14 18:19:06 -0300
commit701677b95764c06bb058c92be11c3a4ad25ab5f2 (patch)
tree3fb3b56c1fa8a39221f42aad9d8bf47e5ee22a69 /tools/perf/util/srcline.c
parentf4c0d5309a3e5f16ca3c3854b1e719dace843e03 (diff)
perf srcline: Add a timeout to reading from addr2line
addr2line may fail to send expected values causing perf to wait indefinitely. Add a 1 second timeout (twice the timeout for reading from /proc/pid/maps) so that such reads don't cause perf to appear to lock up. There are already checks that the file for addr2line contains a debug section but this isn't always sufficient. The problem was observed when a valid elf file would set the configuration for binutils addr2line, then a later read of vmlinux with ELF debug sections would cause a failing write/read which would block indefinitely. As a service to future readers, if the io hits eof or an error, cleanup the addr2line process. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Yang Jihong <yangjihong1@huawei.com> Link: https://lore.kernel.org/r/20230608061812.3715566-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/srcline.c')
-rw-r--r--tools/perf/util/srcline.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index b27b4b3c391b..c013bcbdfd42 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -21,6 +21,8 @@
#include "symbol.h"
#include "subcmd/run-command.h"
+/* If addr2line doesn't return data for 1 second then timeout. */
+int addr2line_timeout_ms = 1 * 1000;
bool srcline_full_filename;
char *srcline__unknown = (char *)"??:0";
@@ -631,7 +633,7 @@ static int addr2line(const char *dso_name, u64 addr,
int len;
char buf[128];
ssize_t written;
- struct io io;
+ struct io io = { .eof = false };
enum a2l_style a2l_style;
if (!a2l) {
@@ -670,7 +672,7 @@ static int addr2line(const char *dso_name, u64 addr,
goto out;
}
io__init(&io, a2l->out, buf, sizeof(buf));
-
+ io.timeout_ms = addr2line_timeout_ms;
switch (read_addr2line_record(&io, a2l_style,
&record_function, &record_filename, &record_line_nr)) {
case -1:
@@ -741,6 +743,10 @@ static int addr2line(const char *dso_name, u64 addr,
out:
free(record_function);
free(record_filename);
+ if (io.eof) {
+ dso->a2l = NULL;
+ addr2line_subprocess_cleanup(a2l);
+ }
return ret;
}