Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
cb8382e0 eedfcb4b

+8 -2
+8 -2
tools/perf/util/map.c
··· 644 644 return printed; 645 645 } 646 646 647 + static 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 + 647 653 static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) 648 654 { 649 655 struct rb_root *root; ··· 688 682 } 689 683 690 684 before->end = map->start; 691 - __maps__insert(maps, before); 685 + __map_groups__insert(pos->groups, before); 692 686 if (verbose >= 2) 693 687 map__fprintf(before, fp); 694 688 } ··· 702 696 } 703 697 704 698 after->start = map->end; 705 - __maps__insert(maps, after); 699 + __map_groups__insert(pos->groups, after); 706 700 if (verbose >= 2) 707 701 map__fprintf(after, fp); 708 702 }