Skip to content

Commit

Permalink
perf symbols: Rebuild rbtree when adjusting symbols for kcore
Browse files Browse the repository at this point in the history
Normally symbols are read from the DSO and adjusted, if need be, so that
the symbol start matches the file offset in the DSO file (we want the
file offset because that is what we know from MMAP events). That is done
by dso__load_sym() which inserts the symbols *after* adjusting them.

In the case of kcore, the symbols have been read from kallsyms and the
symbol start is the memory address. The symbols have to be adjusted to
match the kcore file offsets. dso__split_kallsyms_for_kcore() does that,
but now the adjustment is being done *after* the symbols have been
inserted. It appears dso__split_kallsyms_for_kcore() was assuming that
changing the symbol start would not change the order in the rbtree -
which is, of course, not guaranteed.

Signed-off-by: Adrian Hunter <[email protected]>
Tested-by: Wang Nan <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Zefan Li <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
ahunter6 authored and acmel committed Nov 12, 2015
1 parent f6ba98c commit 866548d
Showing 1 changed file with 14 additions and 16 deletions.
30 changes: 14 additions & 16 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,48 +654,46 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
struct map_groups *kmaps = map__kmaps(map);
struct map *curr_map;
struct symbol *pos;
int count = 0, moved = 0;
int count = 0;
struct rb_root old_root = dso->symbols[map->type];
struct rb_root *root = &dso->symbols[map->type];
struct rb_node *next = rb_first(root);

if (!kmaps)
return -1;

*root = RB_ROOT;

while (next) {
char *module;

pos = rb_entry(next, struct symbol, rb_node);
next = rb_next(&pos->rb_node);

rb_erase_init(&pos->rb_node, &old_root);

module = strchr(pos->name, '\t');
if (module)
*module = '\0';

curr_map = map_groups__find(kmaps, map->type, pos->start);

if (!curr_map || (filter && filter(curr_map, pos))) {
rb_erase_init(&pos->rb_node, root);
symbol__delete(pos);
} else {
pos->start -= curr_map->start - curr_map->pgoff;
if (pos->end)
pos->end -= curr_map->start - curr_map->pgoff;
if (curr_map->dso != map->dso) {
rb_erase_init(&pos->rb_node, root);
symbols__insert(
&curr_map->dso->symbols[curr_map->type],
pos);
++moved;
} else {
++count;
}
continue;
}

pos->start -= curr_map->start - curr_map->pgoff;
if (pos->end)
pos->end -= curr_map->start - curr_map->pgoff;
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
++count;
}

/* Symbols have been adjusted */
dso->adjust_symbols = 1;

return count + moved;
return count;
}

/*
Expand Down

0 comments on commit 866548d

Please sign in to comment.