summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2015-08-24 13:33:14 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-24 13:33:14 -0300
commitc0b4dffbc529244d3e4e3bd392f2bffa2d8531a7 (patch)
treeb38278d90267adfe41667f150c4d21283da0b91b
parent5839a5506de30c23d4cfaf49755cd294f5c48368 (diff)
downloadlinux-c0b4dffbc529244d3e4e3bd392f2bffa2d8531a7.tar.gz
linux-c0b4dffbc529244d3e4e3bd392f2bffa2d8531a7.tar.bz2
linux-c0b4dffbc529244d3e4e3bd392f2bffa2d8531a7.zip
perf annotate: Reset the dso find_symbol cache when removing symbols
The 'annotate' tool does some filtering in the entries in a DSO but forgot to reset the cache done in dso__find_symbol(), cauxing a SEGV: [root@zoo ~]# perf annotate netlink_poll perf: Segmentation fault -------- backtrace -------- perf[0x526ceb] /lib64/libc.so.6(+0x34960)[0x7faedfbe0960] perf(rb_erase+0x223)[0x499d63] perf[0x4213e9] perf[0x4bc123] perf[0x4bc621] perf[0x4bf26b] perf[0x4bc855] perf(perf_session__process_events+0x340)[0x4bddc0] perf(cmd_annotate+0x6bb)[0x421b5b] perf[0x479063] perf(main+0x60a)[0x42098a] /lib64/libc.so.6(__libc_start_main+0xf0)[0x7faedfbcbfe0] perf[0x420aa9] [0x0] [root@zoo ~]# Fix it by reseting the find cache when removing symbols. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Borislav Petkov <bp@suse.de> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Stephane Eranian <eranian@google.com> Fixes: b685ac22b436 ("perf symbols: Add front end cache for DSO symbol lookup") Link: http://lkml.kernel.org/n/tip-b2y9x46y0t8yem1ive41zqyp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-annotate.c1
-rw-r--r--tools/perf/util/dso.h2
-rw-r--r--tools/perf/util/symbol.c10
3 files changed, 13 insertions, 0 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index a32a64ef08e2..8edc205ff9a7 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -67,6 +67,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
rb_erase(&al->sym->rb_node,
&al->map->dso->symbols[al->map->type]);
symbol__delete(al->sym);
+ dso__reset_find_symbol_cache(al->map->dso);
}
return 0;
}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c73276db6d6f..fc8db9c764ac 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -324,6 +324,8 @@ struct dso *__dsos__findnew(struct dsos *dsos, const char *name);
struct dso *dsos__findnew(struct dsos *dsos, const char *name);
bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
+void dso__reset_find_symbol_cache(struct dso *dso);
+
size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
bool (skip)(struct dso *dso, int parm), int parm);
size_t __dsos__fprintf(struct list_head *head, FILE *fp);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 42e98ab5a9bb..46ae0532a8a6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -441,6 +441,16 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols,
return &s->sym;
}
+void dso__reset_find_symbol_cache(struct dso *dso)
+{
+ enum map_type type;
+
+ for (type = MAP__FUNCTION; type <= MAP__VARIABLE; ++type) {
+ dso->last_find_result[type].addr = 0;
+ dso->last_find_result[type].symbol = NULL;
+ }
+}
+
struct symbol *dso__find_symbol(struct dso *dso,
enum map_type type, u64 addr)
{