perf tools: fix off-by-one error in maps
PATCH 1/1 perf tools: fix off-by-one error in maps
This patch fixes off-by-one errors in the management of maps. A map is defined by start address and length as implemented by map__new():
map__init(map, type, start, start + len, pgoff, dso);
map__init()
{
map->start = addr;
map->end = end;
}
Consequently, the actual address range is ]start; end[ map->end is the first byte outside the range. This patch fixes two bugs where upper bounds were off-by-one.
tools/perf/util/map.c +2 -2
@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,int map_groups__find_ams (struct addr_map_symbol *ams,symbol_filter_t filter) { -if (ams->addr < ams->map->start || ams->addr > ams->map->end) { +if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {if (ams->map->groups ==NULL )return -1 ; ams->map = map_groups__find(ams->map->groups, ams->map->type,
@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - after->start = map->end +1 ; + after->start = map->end;map_groups__insert (mg, after);if (verbose >=2 )map__fprintf (after, fp);
Quoted 1 line · Stephane Eranian
SNIP
Quoted 16 lines
Signed-off-by Stephane Eranian <[email protected]>tools/perf/util/map.c +1
-1@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,int map_groups__find_ams (struct addr_map_symbol *ams,symbol_filter_t filter) { -if (ams->addr < ams->map->start || ams->addr > ams->map->end) { +if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {if (ams->map->groups ==NULL )return -1 ; ams->map = map_groups__find(ams->map->groups, ams->map->type,
tools/perf/util/map.c int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, · line 684
Quoted 8 lines
tools/perf/util/map.c +1
-1@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - after->start = map->end +1 ; + after->start = map->end;map_groups__insert (mg, after);if (verbose >=2 )map__fprintf (after, fp);
hum, do we also need this one then?
---
tools/perf/util/map.c +1 -1
@@ -664,7 +664,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - before->end = map->start -1 ; + before->end = map->start;map_groups__insert (mg, before);if (verbose >=2 )map__fprintf (before, fp);
Quoted 38 lines · Jiri Olsa
Quoted 1 line · Stephane Eranian
SNIP
Quoted 16 lines
Signed-off-by Stephane Eranian <[email protected]>tools/perf/util/map.c +1
-1@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,int map_groups__find_ams (struct addr_map_symbol *ams,symbol_filter_t filter) { -if (ams->addr < ams->map->start || ams->addr > ams->map->end) { +if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {if (ams->map->groups ==NULL )return -1 ; ams->map = map_groups__find(ams->map->groups, ams->map->type,tools/perf/util/map.c int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, · line 684
Quoted 8 lines
tools/perf/util/map.c +1
-1@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - after->start = map->end +1 ; + after->start = map->end;map_groups__insert (mg, after);if (verbose >=2 )map__fprintf (after, fp);hum, do we also need this one then?
---
tools/perf/util/map.c +0
-0
tools/perf/util/map.c int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, · line 667
Quoted 5 lines
tools/perf/util/map.c +1
-1@@ -664,7 +664,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - before->end = map->start -1 ; + before->end = map->start;
Start is first byte of next range, so it is pointing to one byte after the end of the before range.
So, yes, I think we need your fix as well. I missed it. Will repost.
Quoted 3 lines
tools/perf/util/map.c +0
-0map_groups__insert (mg, before);if (verbose >=2 )map__fprintf (before, fp);
Em Fri, Oct 03, 2014 at 12:47:07PM +0200, Stephane Eranian escreveu:
Quoted 7 lines
This patch fixes off-by-one errors in the management of maps. A map is defined by start address and length as implemented by
map__new():
map__init(map, type, start, start + len, pgoff, dso);
Quoted 8 lines
map__init()
{
map->start= addr;
map->end= end;
}Consequently, the actual address range is ]start; end[
map->endis the first byte outside the range. This patch
I thought map->end should be the end of the range, not something after the end, is that really the case?
I.e. the bug would be in that call to map__init, that should instead be:
map__init(map, type, start, start + len - 1, pgoff, dso);
no? Isn't that clearer, i.e. to keep the semantics of 'end'?
- Arnaldo
Quoted 26 lines
fixes two bugs where upper bounds were off-by-one.
Signed-off-by Stephane Eranian <[email protected]>tools/perf/util/map.c +2
-2@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,int map_groups__find_ams (struct addr_map_symbol *ams,symbol_filter_t filter) { -if (ams->addr < ams->map->start || ams->addr > ams->map->end) { +if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {if (ams->map->groups ==NULL )return -1 ; ams->map = map_groups__find(ams->map->groups, ams->map->type,@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - after->start = map->end +1 ; + after->start = map->end;map_groups__insert (mg, after);if (verbose >=2 )map__fprintf (after, fp);
Arnaldo,
Quoted 14 lines · Arnaldo Carvalho de Melo
Em Fri, Oct 03, 2014 at 12:47:07PM +0200, Stephane Eranian escreveu:
Quoted 13 lines
This patch fixes off-by-one errors in the management of maps. A map is defined by start address and length as implemented by
map__new():
map__init(map, type, start, start + len, pgoff, dso);
map__init()
{
map->start= addr;
map->end= end;
}
Quoted 6 lines
Quoted 2 lines
Consequently, the actual address range is ]start; end[
map->endis the first byte outside the range. This patchI thought
map->endshould be the end of the range, not something after the end, is that really the case?
map->start = start;map->end = start + len;
Thus map->end is the first byte after the end.
Quoted 3 lines
I.e. the bug would be in that call to
map__init, that should instead be:map__init(map, type, start, start + len - 1, pgoff, dso);
Yeah, that is the alternative. But are you sure this is the only place where a map
is initialized. And this is not really C like.
Quoted 3 lines
no? Isn't that clearer, i.e. to keep the semantics of 'end'?
Yeah, it all depends on what you meant by end: last byte or first byte after. But then everything needs to be consistent. That is what I am trying to fix in this patch.
Quoted 28 lines
- Arnaldo
Quoted 26 lines
fixes two bugs where upper bounds were off-by-one.
Signed-off-by Stephane Eranian <[email protected]>tools/perf/util/map.c +2
-2@@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,int map_groups__find_ams (struct addr_map_symbol *ams,symbol_filter_t filter) { -if (ams->addr < ams->map->start || ams->addr > ams->map->end) { +if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {if (ams->map->groups ==NULL )return -1 ; ams->map = map_groups__find(ams->map->groups, ams->map->type,@@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, goto move_map; } - after->start = map->end +1 ; + after->start = map->end;map_groups__insert (mg, after);if (verbose >=2 )map__fprintf (after, fp);