diff options
author | Rabin Vincent <rabin.vincent@axis.com> | 2015-09-27 14:37:57 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-10-12 22:25:25 -0400 |
commit | 8eac1d5e9256260b9cc3bfcdd9b8b995990950f5 (patch) | |
tree | 0e397d62a4982904b86f2cc9c8c281c712785010 /tools/perf | |
parent | 4aa8e454d347a1c96a2322683a6798de7e17da5f (diff) |
perf callchain: Use debug_frame if eh_frame is unusable
When NO_LIBUNWIND_DEBUG_FRAME=0, use the .debug_frame if the .eh_frame
doesn't contain the approprate unwind tables.
Signed-off-by: Rabin Vincent <rabin.vincent@axis.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Rabin Vincent <rabinv@axis.com>
Link: http://lkml.kernel.org/r/1443379079-29133-3-git-send-email-rabin.vincent@axis.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 4c00507ee3fd..ea993f6c7e0c 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -330,6 +330,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, | |||
330 | struct map *map; | 330 | struct map *map; |
331 | unw_dyn_info_t di; | 331 | unw_dyn_info_t di; |
332 | u64 table_data, segbase, fde_count; | 332 | u64 table_data, segbase, fde_count; |
333 | int ret = -EINVAL; | ||
333 | 334 | ||
334 | map = find_map(ip, ui); | 335 | map = find_map(ip, ui); |
335 | if (!map || !map->dso) | 336 | if (!map || !map->dso) |
@@ -348,13 +349,14 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, | |||
348 | di.u.rti.table_data = map->start + table_data; | 349 | di.u.rti.table_data = map->start + table_data; |
349 | di.u.rti.table_len = fde_count * sizeof(struct table_entry) | 350 | di.u.rti.table_len = fde_count * sizeof(struct table_entry) |
350 | / sizeof(unw_word_t); | 351 | / sizeof(unw_word_t); |
351 | return dwarf_search_unwind_table(as, ip, &di, pi, | 352 | ret = dwarf_search_unwind_table(as, ip, &di, pi, |
352 | need_unwind_info, arg); | 353 | need_unwind_info, arg); |
353 | } | 354 | } |
354 | 355 | ||
355 | #ifndef NO_LIBUNWIND_DEBUG_FRAME | 356 | #ifndef NO_LIBUNWIND_DEBUG_FRAME |
356 | /* Check the .debug_frame section for unwinding info */ | 357 | /* Check the .debug_frame section for unwinding info */ |
357 | if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { | 358 | if (ret < 0 && |
359 | !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { | ||
358 | int fd = dso__data_get_fd(map->dso, ui->machine); | 360 | int fd = dso__data_get_fd(map->dso, ui->machine); |
359 | int is_exec = elf_is_exec(fd, map->dso->name); | 361 | int is_exec = elf_is_exec(fd, map->dso->name); |
360 | unw_word_t base = is_exec ? 0 : map->start; | 362 | unw_word_t base = is_exec ? 0 : map->start; |
@@ -370,7 +372,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, | |||
370 | } | 372 | } |
371 | #endif | 373 | #endif |
372 | 374 | ||
373 | return -EINVAL; | 375 | return ret; |
374 | } | 376 | } |
375 | 377 | ||
376 | static int access_fpreg(unw_addr_space_t __maybe_unused as, | 378 | static int access_fpreg(unw_addr_space_t __maybe_unused as, |