summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2015-11-04 09:08:11 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-11-05 09:39:38 -0500
commitcb8382e05817a8104ea0edb63b8e37b8fbecd14c (patch)
tree65a5f24103003c51b42f1d4387f7e1ef671c28e6 /tools
parenteedfcb4bc5f0185a14fc9e1e5a9770ad833ea5a4 (diff)
perf tools: Insert split maps correctly into origin group
When new maps are cloned out of split map they are added into origin map's group, but their groups pointer is not updated. This could lead to a segfault, because map->groups is expected to be always set as reported by Markus: __map__is_kernel (map=map@entry=0x1abb7a0) at util/map.c:238 238 return __machine__kernel_map(map->groups->machine, map->type) = (gdb) bt #0 __map__is_kernel (map=map@entry=0x1abb7a0) at util/map.c:238 #1 0x00000000004393e4 in symbol_filter (map=map@entry=0x1abb7a0, sym=sym@entry #2 0x00000000004fcd4d in dso__load_sym (dso=dso@entry=0x166dae0, map=map@entry #3 0x00000000004a64e0 in dso__load (dso=0x166dae0, map=map@entry=0x1abb7a0, fi #4 0x00000000004b941f in map__load (filter=0x4393c0 <symbol_filter>, map=<opti #5 map__find_symbol (map=0x1abb7a0, addr=40188, filter=0x4393c0 <symbol_filter ... Adding __map_groups__insert function to add map into groups together with map->groups pointer update. It takes no lock as opposed to existing map_groups__insert, as maps__fixup_overlappings(), where it is being called, already has the necessary lock held. Using __map_groups__insert to add new maps after map split. Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Markus Trippelsdorf <markus@trippelsdorf.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20151104140811.GA32664@krava.brq.redhat.com Fixes: cfc5acd4c80b ("perf top: Filter symbols based on __map__is_kernel(map)") Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/map.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4e38c396a897..afc6b56cf749 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -644,6 +644,12 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
644 return printed; 644 return printed;
645} 645}
646 646
647static void __map_groups__insert(struct map_groups *mg, struct map *map)
648{
649 __maps__insert(&mg->maps[map->type], map);
650 map->groups = mg;
651}
652
647static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) 653static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
648{ 654{
649 struct rb_root *root; 655 struct rb_root *root;
@@ -682,7 +688,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
682 } 688 }
683 689
684 before->end = map->start; 690 before->end = map->start;
685 __maps__insert(maps, before); 691 __map_groups__insert(pos->groups, before);
686 if (verbose >= 2) 692 if (verbose >= 2)
687 map__fprintf(before, fp); 693 map__fprintf(before, fp);
688 } 694 }
@@ -696,7 +702,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
696 } 702 }
697 703
698 after->start = map->end; 704 after->start = map->end;
699 __maps__insert(maps, after); 705 __map_groups__insert(pos->groups, after);
700 if (verbose >= 2) 706 if (verbose >= 2)
701 map__fprintf(after, fp); 707 map__fprintf(after, fp);
702 } 708 }