diff options
| -rw-r--r-- | tools/perf/util/thread.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/unwind-libunwind.c | 37 | ||||
| -rw-r--r-- | tools/perf/util/unwind.h | 17 |
3 files changed, 55 insertions, 5 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index a9df7f2c6dc9..2b7b2d91c016 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "util.h" | 7 | #include "util.h" |
| 8 | #include "debug.h" | 8 | #include "debug.h" |
| 9 | #include "comm.h" | 9 | #include "comm.h" |
| 10 | #include "unwind.h" | ||
| 10 | 11 | ||
| 11 | int thread__init_map_groups(struct thread *thread, struct machine *machine) | 12 | int thread__init_map_groups(struct thread *thread, struct machine *machine) |
| 12 | { | 13 | { |
| @@ -37,6 +38,9 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
| 37 | thread->cpu = -1; | 38 | thread->cpu = -1; |
| 38 | INIT_LIST_HEAD(&thread->comm_list); | 39 | INIT_LIST_HEAD(&thread->comm_list); |
| 39 | 40 | ||
| 41 | if (unwind__prepare_access(thread) < 0) | ||
| 42 | goto err_thread; | ||
| 43 | |||
| 40 | comm_str = malloc(32); | 44 | comm_str = malloc(32); |
| 41 | if (!comm_str) | 45 | if (!comm_str) |
| 42 | goto err_thread; | 46 | goto err_thread; |
| @@ -48,6 +52,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
| 48 | goto err_thread; | 52 | goto err_thread; |
| 49 | 53 | ||
| 50 | list_add(&comm->list, &thread->comm_list); | 54 | list_add(&comm->list, &thread->comm_list); |
| 55 | |||
| 51 | } | 56 | } |
| 52 | 57 | ||
| 53 | return thread; | 58 | return thread; |
| @@ -69,6 +74,7 @@ void thread__delete(struct thread *thread) | |||
| 69 | list_del(&comm->list); | 74 | list_del(&comm->list); |
| 70 | comm__free(comm); | 75 | comm__free(comm); |
| 71 | } | 76 | } |
| 77 | unwind__finish_access(thread); | ||
| 72 | 78 | ||
| 73 | free(thread); | 79 | free(thread); |
| 74 | } | 80 | } |
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 92b56db52471..e060386165c5 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <libunwind.h> | 25 | #include <libunwind.h> |
| 26 | #include <libunwind-ptrace.h> | 26 | #include <libunwind-ptrace.h> |
| 27 | #include "callchain.h" | ||
| 27 | #include "thread.h" | 28 | #include "thread.h" |
| 28 | #include "session.h" | 29 | #include "session.h" |
| 29 | #include "perf_regs.h" | 30 | #include "perf_regs.h" |
| @@ -525,12 +526,12 @@ static unw_accessors_t accessors = { | |||
| 525 | .get_proc_name = get_proc_name, | 526 | .get_proc_name = get_proc_name, |
| 526 | }; | 527 | }; |
| 527 | 528 | ||
| 528 | static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | 529 | int unwind__prepare_access(struct thread *thread) |
| 529 | void *arg, int max_stack) | ||
| 530 | { | 530 | { |
| 531 | unw_addr_space_t addr_space; | 531 | unw_addr_space_t addr_space; |
| 532 | unw_cursor_t c; | 532 | |
| 533 | int ret; | 533 | if (callchain_param.record_mode != CALLCHAIN_DWARF) |
| 534 | return 0; | ||
| 534 | 535 | ||
| 535 | addr_space = unw_create_addr_space(&accessors, 0); | 536 | addr_space = unw_create_addr_space(&accessors, 0); |
| 536 | if (!addr_space) { | 537 | if (!addr_space) { |
| @@ -538,6 +539,33 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | |||
| 538 | return -ENOMEM; | 539 | return -ENOMEM; |
| 539 | } | 540 | } |
| 540 | 541 | ||
| 542 | thread__set_priv(thread, addr_space); | ||
| 543 | |||
| 544 | return 0; | ||
| 545 | } | ||
| 546 | |||
| 547 | void unwind__finish_access(struct thread *thread) | ||
| 548 | { | ||
| 549 | unw_addr_space_t addr_space; | ||
| 550 | |||
| 551 | if (callchain_param.record_mode != CALLCHAIN_DWARF) | ||
| 552 | return; | ||
| 553 | |||
| 554 | addr_space = thread__priv(thread); | ||
| 555 | unw_destroy_addr_space(addr_space); | ||
| 556 | } | ||
| 557 | |||
| 558 | static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | ||
| 559 | void *arg, int max_stack) | ||
| 560 | { | ||
| 561 | unw_addr_space_t addr_space; | ||
| 562 | unw_cursor_t c; | ||
| 563 | int ret; | ||
| 564 | |||
| 565 | addr_space = thread__priv(ui->thread); | ||
| 566 | if (addr_space == NULL) | ||
| 567 | return -1; | ||
| 568 | |||
| 541 | ret = unw_init_remote(&c, addr_space, ui); | 569 | ret = unw_init_remote(&c, addr_space, ui); |
| 542 | if (ret) | 570 | if (ret) |
| 543 | display_error(ret); | 571 | display_error(ret); |
| @@ -549,7 +577,6 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | |||
| 549 | ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0; | 577 | ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0; |
| 550 | } | 578 | } |
| 551 | 579 | ||
| 552 | unw_destroy_addr_space(addr_space); | ||
| 553 | return ret; | 580 | return ret; |
| 554 | } | 581 | } |
| 555 | 582 | ||
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index f03061260b4e..c17c4855bdbc 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include "event.h" | 5 | #include "event.h" |
| 6 | #include "symbol.h" | 6 | #include "symbol.h" |
| 7 | #include "thread.h" | ||
| 7 | 8 | ||
| 8 | struct unwind_entry { | 9 | struct unwind_entry { |
| 9 | struct map *map; | 10 | struct map *map; |
| @@ -21,6 +22,15 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
| 21 | /* libunwind specific */ | 22 | /* libunwind specific */ |
| 22 | #ifdef HAVE_LIBUNWIND_SUPPORT | 23 | #ifdef HAVE_LIBUNWIND_SUPPORT |
| 23 | int libunwind__arch_reg_id(int regnum); | 24 | int libunwind__arch_reg_id(int regnum); |
| 25 | int unwind__prepare_access(struct thread *thread); | ||
| 26 | void unwind__finish_access(struct thread *thread); | ||
| 27 | #else | ||
| 28 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | ||
| 29 | { | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | ||
| 24 | #endif | 34 | #endif |
| 25 | #else | 35 | #else |
| 26 | static inline int | 36 | static inline int |
| @@ -33,5 +43,12 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, | |||
| 33 | { | 43 | { |
| 34 | return 0; | 44 | return 0; |
| 35 | } | 45 | } |
| 46 | |||
| 47 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | ||
| 48 | { | ||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | ||
| 36 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | 53 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ |
| 37 | #endif /* __UNWIND_H */ | 54 | #endif /* __UNWIND_H */ |
