tools, perf: Fix symbol offset fallback path in get_srcline
PATCH 1/1 tools, perf: Fix symbol offset fallback path in get_srcline
From: Andi Kleen <[email protected]>
[This is a bug fix over the earlier branch callstack patchkit]
get_srcline has a fallback path when it cannot find the line number for an address: it returns sym+offset.
The normal line number resolution process uses the al_addr, which is the address relative to the start of the DSO. However to compute the offset from the symbol we need the absolute address.
Since the dso start offset is not easily available here just pass it in from the caller.
In theory it would be tempting to move the 2objdump conversion call into get_srcline, but I think that would slow down annotate quite a bit which caches it, so I didn't do it.
Signed-off-by Andi Kleen <[email protected]>
--- tools/perf/util/annotate.c | 3 ++- tools/perf/util/callchain.c | 2 +- tools/perf/util/map.c | 3 ++- tools/perf/util/sort.c | 6 ++++-- tools/perf/util/srcline.c | 6 +++--- tools/perf/util/util.h | 2 +- 6 files changed, 13 insertions(+), 9 deletions(-)
tools/perf/util/annotate.c +2 -1
@@ -1190,7 +1190,8 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, goto next; offset = start + i; - src_line->path =get_srcline (map->dso, offset,NULL , false); + src_line->path =get_srcline (map->dso, offset,NULL , false, + sym->start + i);insert_source_line (&tmp_root, src_line); next:
tools/perf/util/callchain.c +1 -1
@@ -824,7 +824,7 @@ char *callchain_list__sym_name(struct callchain_list *cl, cl->srcline =get_srcline (cl->ms.map->dso,map__rip_2objdump (cl->ms.map, cl->ip), - cl->ms.sym, false); + cl->ms.sym, false, cl->ip);if (cl->srcline) printed =scnprintf (bf, bfsize,"%s %s" , cl->ms.sym->name, cl->srcline);
tools/perf/util/map.c +2 -1
@@ -360,7 +360,8 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,if (map && map->dso) { srcline =get_srcline (map->dso, -map__rip_2objdump (map, addr),NULL , true); +map__rip_2objdump (map, addr),NULL , true, + addr);if (srcline !=SRCLINE_UNKNOWN ) ret =fprintf (fp,"%s%s" , prefix, srcline);free_srcline (srcline);
tools/perf/util/sort.c +4 -2
@@ -292,7 +292,8 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)struct map *map = left->ms.map; left->srcline =get_srcline (map->dso,map__rip_2objdump (map, left->ip), - left->ms.sym, true); + left->ms.sym, true, + left->ip); } }if (!right->srcline) {
@@ -302,7 +303,8 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)struct map *map = right->ms.map; right->srcline =get_srcline (map->dso,map__rip_2objdump (map, right->ip), - right->ms.sym, true); + right->ms.sym, true, + right->ip); } }return strcmp (right->srcline, left->srcline);
tools/perf/util/srcline.c +3 -3
@@ -252,7 +252,7 @@ void dso__free_a2l(struct dso *dso __maybe_unused)#define A2L_FAIL_LIMIT 123char *get_srcline (struct dso *dso,unsigned long addr,struct symbol *sym, -bool show_sym) +bool show_sym,unsigned long abs_addr) {char *file =NULL ;unsigned line =0 ;
@@ -293,9 +293,9 @@ out: }if (sym) {if (asprintf (&srcline,"%s+%ld" , show_sym ? sym->name :"" , - addr - sym->start) <0 ) + abs_addr - sym->start) <0 )return SRCLINE_UNKNOWN ; - }else if (asprintf (&srcline,"%s[%lx]" , dso->short_name, addr) <0 ) + }else if (asprintf (&srcline,"%s[%lx]" , dso->short_name, abs_addr) <0 )return SRCLINE_UNKNOWN ;return srcline; }
tools/perf/util/util.h +1 -1
@@ -341,7 +341,7 @@ struct dso;struct symbol ;char *get_srcline (struct dso *dso,unsigned long addr,struct symbol *sym, -bool show_sym); +bool show_sym,unsigned long abs_addr);void free_srcline (char *srcline);int filename__read_int (const char *filename,int *value);
Signature · 1 line
1.9.3