|
@@ -149,8 +149,11 @@ static void addr2line_cleanup(struct a2l_data *a2l)
|
|
|
free(a2l);
|
|
|
}
|
|
|
|
|
|
+#define MAX_INLINE_NEST 1024
|
|
|
+
|
|
|
static int addr2line(const char *dso_name, u64 addr,
|
|
|
- char **file, unsigned int *line, struct dso *dso)
|
|
|
+ char **file, unsigned int *line, struct dso *dso,
|
|
|
+ bool unwind_inlines)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
struct a2l_data *a2l = dso->a2l;
|
|
@@ -170,6 +173,15 @@ static int addr2line(const char *dso_name, u64 addr,
|
|
|
|
|
|
bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
|
|
|
|
|
|
+ if (a2l->found && unwind_inlines) {
|
|
|
+ int cnt = 0;
|
|
|
+
|
|
|
+ while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
|
|
|
+ &a2l->funcname, &a2l->line) &&
|
|
|
+ cnt++ < MAX_INLINE_NEST)
|
|
|
+ ;
|
|
|
+ }
|
|
|
+
|
|
|
if (a2l->found && a2l->filename) {
|
|
|
*file = strdup(a2l->filename);
|
|
|
*line = a2l->line;
|
|
@@ -197,7 +209,8 @@ void dso__free_a2l(struct dso *dso)
|
|
|
|
|
|
static int addr2line(const char *dso_name, u64 addr,
|
|
|
char **file, unsigned int *line_nr,
|
|
|
- struct dso *dso __maybe_unused)
|
|
|
+ struct dso *dso __maybe_unused,
|
|
|
+ bool unwind_inlines __maybe_unused)
|
|
|
{
|
|
|
FILE *fp;
|
|
|
char cmd[PATH_MAX];
|
|
@@ -254,8 +267,8 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
|
|
|
*/
|
|
|
#define A2L_FAIL_LIMIT 123
|
|
|
|
|
|
-char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
|
|
|
- bool show_sym)
|
|
|
+char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
|
|
|
+ bool show_sym, bool unwind_inlines)
|
|
|
{
|
|
|
char *file = NULL;
|
|
|
unsigned line = 0;
|
|
@@ -276,7 +289,7 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
|
|
|
if (!strncmp(dso_name, "/tmp/perf-", 10))
|
|
|
goto out;
|
|
|
|
|
|
- if (!addr2line(dso_name, addr, &file, &line, dso))
|
|
|
+ if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
|
|
|
goto out;
|
|
|
|
|
|
if (asprintf(&srcline, "%s:%u",
|
|
@@ -310,3 +323,9 @@ void free_srcline(char *srcline)
|
|
|
if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
|
|
|
free(srcline);
|
|
|
}
|
|
|
+
|
|
|
+char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
|
|
|
+ bool show_sym)
|
|
|
+{
|
|
|
+ return __get_srcline(dso, addr, sym, show_sym, false);
|
|
|
+}
|