[PATCH] tools, perf: Fix symbol offset fallback path in get_srcline
From: Andi Kleen
Date: Thu Nov 13 2014 - 18:15:01 EST
From: Andi Kleen <ak@xxxxxxxxxxxxxxx>
[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 <ak@xxxxxxxxxxxxxxx>
---
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(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 9837adf..acb3a4e9 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -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:
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index cf524a3..00c9891 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -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);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 62ca9f2..5550f7a 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -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);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 95efaaf..d89e5d3 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -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);
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 36a7aff..7f5a8e8 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -252,7 +252,7 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
#define A2L_FAIL_LIMIT 123
char *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;
}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 921c48b..2ed8536 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -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);
--
1.9.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/