OSDN Git Service

perf annotate: Reset the dso find_symbol cache when removing symbols
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 24 Aug 2015 16:33:14 +0000 (13:33 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 24 Aug 2015 16:33:14 +0000 (13:33 -0300)
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>
tools/perf/builtin-annotate.c
tools/perf/util/dso.h
tools/perf/util/symbol.c

index a32a64e..8edc205 100644 (file)
@@ -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;
        }
index c73276d..fc8db9c 100644 (file)
@@ -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);
index 42e98ab..46ae053 100644 (file)
@@ -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)
 {