diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-01-19 07:09:01 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-01-19 07:09:01 -0500 |
commit | 45e6af06367e7b2eb8dc49671092462d8f8a5f47 (patch) | |
tree | 68187bf0c9d8a1eb653d230dbd0d38ffd0046a27 /tools | |
parent | 3e7e09dbd1080de5dcf10092830e39bc2e2932ec (diff) | |
parent | 2a29190c040c0b11e39197c67abf6f87e0a61f9a (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf improvements and fixes from Arnaldo Carvalho de Melo:
Infrastructure changes:
* Improve callchain processing by removing unnecessary work. (Frederic Weisbecker)
* Fix comm override error handling (Frederic Weisbecker)
* Improve 'perf probe' exit path, release resources (Masami Hiramatsu)
* Improve libtraceevent plugins exit path, allowing the registering of
an unregister handler to be called at exit time (Namhyung Kim)
* Add an alias to the build test makefile (make -C tools/perf build-test)
(Namhyung Kim)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 136 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 5 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_cfg80211.c | 6 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_function.c | 3 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_hrtimer.c | 10 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_jbd2.c | 9 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_kmem.c | 22 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_kvm.c | 29 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_mac80211.c | 7 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_sched_switch.c | 12 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_scsi.c | 6 | ||||
-rw-r--r-- | tools/lib/traceevent/plugin_xen.c | 6 | ||||
-rw-r--r-- | tools/perf/Makefile | 6 | ||||
-rw-r--r-- | tools/perf/builtin-probe.c | 48 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 23 | ||||
-rw-r--r-- | tools/perf/util/comm.c | 19 | ||||
-rw-r--r-- | tools/perf/util/comm.h | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 111 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 6 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 5 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 5 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 5 | ||||
-rw-r--r-- | tools/perf/util/unwind.c | 20 |
23 files changed, 389 insertions, 112 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 2ce565a73dd5..1587ea392ad6 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -5561,6 +5561,52 @@ int pevent_register_print_function(struct pevent *pevent, | |||
5561 | } | 5561 | } |
5562 | 5562 | ||
5563 | /** | 5563 | /** |
5564 | * pevent_unregister_print_function - unregister a helper function | ||
5565 | * @pevent: the handle to the pevent | ||
5566 | * @func: the function to process the helper function | ||
5567 | * @name: the name of the helper function | ||
5568 | * | ||
5569 | * This function removes existing print handler for function @name. | ||
5570 | * | ||
5571 | * Returns 0 if the handler was removed successully, -1 otherwise. | ||
5572 | */ | ||
5573 | int pevent_unregister_print_function(struct pevent *pevent, | ||
5574 | pevent_func_handler func, char *name) | ||
5575 | { | ||
5576 | struct pevent_function_handler *func_handle; | ||
5577 | |||
5578 | func_handle = find_func_handler(pevent, name); | ||
5579 | if (func_handle && func_handle->func == func) { | ||
5580 | remove_func_handler(pevent, name); | ||
5581 | return 0; | ||
5582 | } | ||
5583 | return -1; | ||
5584 | } | ||
5585 | |||
5586 | static struct event_format *pevent_search_event(struct pevent *pevent, int id, | ||
5587 | const char *sys_name, | ||
5588 | const char *event_name) | ||
5589 | { | ||
5590 | struct event_format *event; | ||
5591 | |||
5592 | if (id >= 0) { | ||
5593 | /* search by id */ | ||
5594 | event = pevent_find_event(pevent, id); | ||
5595 | if (!event) | ||
5596 | return NULL; | ||
5597 | if (event_name && (strcmp(event_name, event->name) != 0)) | ||
5598 | return NULL; | ||
5599 | if (sys_name && (strcmp(sys_name, event->system) != 0)) | ||
5600 | return NULL; | ||
5601 | } else { | ||
5602 | event = pevent_find_event_by_name(pevent, sys_name, event_name); | ||
5603 | if (!event) | ||
5604 | return NULL; | ||
5605 | } | ||
5606 | return event; | ||
5607 | } | ||
5608 | |||
5609 | /** | ||
5564 | * pevent_register_event_handler - register a way to parse an event | 5610 | * pevent_register_event_handler - register a way to parse an event |
5565 | * @pevent: the handle to the pevent | 5611 | * @pevent: the handle to the pevent |
5566 | * @id: the id of the event to register | 5612 | * @id: the id of the event to register |
@@ -5584,20 +5630,9 @@ int pevent_register_event_handler(struct pevent *pevent, int id, | |||
5584 | struct event_format *event; | 5630 | struct event_format *event; |
5585 | struct event_handler *handle; | 5631 | struct event_handler *handle; |
5586 | 5632 | ||
5587 | if (id >= 0) { | 5633 | event = pevent_search_event(pevent, id, sys_name, event_name); |
5588 | /* search by id */ | 5634 | if (event == NULL) |
5589 | event = pevent_find_event(pevent, id); | 5635 | goto not_found; |
5590 | if (!event) | ||
5591 | goto not_found; | ||
5592 | if (event_name && (strcmp(event_name, event->name) != 0)) | ||
5593 | goto not_found; | ||
5594 | if (sys_name && (strcmp(sys_name, event->system) != 0)) | ||
5595 | goto not_found; | ||
5596 | } else { | ||
5597 | event = pevent_find_event_by_name(pevent, sys_name, event_name); | ||
5598 | if (!event) | ||
5599 | goto not_found; | ||
5600 | } | ||
5601 | 5636 | ||
5602 | pr_stat("overriding event (%d) %s:%s with new print handler", | 5637 | pr_stat("overriding event (%d) %s:%s with new print handler", |
5603 | event->id, event->system, event->name); | 5638 | event->id, event->system, event->name); |
@@ -5637,6 +5672,79 @@ int pevent_register_event_handler(struct pevent *pevent, int id, | |||
5637 | return -1; | 5672 | return -1; |
5638 | } | 5673 | } |
5639 | 5674 | ||
5675 | static int handle_matches(struct event_handler *handler, int id, | ||
5676 | const char *sys_name, const char *event_name, | ||
5677 | pevent_event_handler_func func, void *context) | ||
5678 | { | ||
5679 | if (id >= 0 && id != handler->id) | ||
5680 | return 0; | ||
5681 | |||
5682 | if (event_name && (strcmp(event_name, handler->event_name) != 0)) | ||
5683 | return 0; | ||
5684 | |||
5685 | if (sys_name && (strcmp(sys_name, handler->sys_name) != 0)) | ||
5686 | return 0; | ||
5687 | |||
5688 | if (func != handler->func || context != handler->context) | ||
5689 | return 0; | ||
5690 | |||
5691 | return 1; | ||
5692 | } | ||
5693 | |||
5694 | /** | ||
5695 | * pevent_unregister_event_handler - unregister an existing event handler | ||
5696 | * @pevent: the handle to the pevent | ||
5697 | * @id: the id of the event to unregister | ||
5698 | * @sys_name: the system name the handler belongs to | ||
5699 | * @event_name: the name of the event handler | ||
5700 | * @func: the function to call to parse the event information | ||
5701 | * @context: the data to be passed to @func | ||
5702 | * | ||
5703 | * This function removes existing event handler (parser). | ||
5704 | * | ||
5705 | * If @id is >= 0, then it is used to find the event. | ||
5706 | * else @sys_name and @event_name are used. | ||
5707 | * | ||
5708 | * Returns 0 if handler was removed successfully, -1 if event was not found. | ||
5709 | */ | ||
5710 | int pevent_unregister_event_handler(struct pevent *pevent, int id, | ||
5711 | const char *sys_name, const char *event_name, | ||
5712 | pevent_event_handler_func func, void *context) | ||
5713 | { | ||
5714 | struct event_format *event; | ||
5715 | struct event_handler *handle; | ||
5716 | struct event_handler **next; | ||
5717 | |||
5718 | event = pevent_search_event(pevent, id, sys_name, event_name); | ||
5719 | if (event == NULL) | ||
5720 | goto not_found; | ||
5721 | |||
5722 | if (event->handler == func && event->context == context) { | ||
5723 | pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.", | ||
5724 | event->id, event->system, event->name); | ||
5725 | |||
5726 | event->handler = NULL; | ||
5727 | event->context = NULL; | ||
5728 | return 0; | ||
5729 | } | ||
5730 | |||
5731 | not_found: | ||
5732 | for (next = &pevent->handlers; *next; next = &(*next)->next) { | ||
5733 | handle = *next; | ||
5734 | if (handle_matches(handle, id, sys_name, event_name, | ||
5735 | func, context)) | ||
5736 | break; | ||
5737 | } | ||
5738 | |||
5739 | if (!(*next)) | ||
5740 | return -1; | ||
5741 | |||
5742 | *next = handle->next; | ||
5743 | free_handler(handle); | ||
5744 | |||
5745 | return 0; | ||
5746 | } | ||
5747 | |||
5640 | /** | 5748 | /** |
5641 | * pevent_alloc - create a pevent handle | 5749 | * pevent_alloc - create a pevent handle |
5642 | */ | 5750 | */ |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index a3beca56cb35..791c539374c7 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -624,10 +624,15 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt, | |||
624 | int pevent_register_event_handler(struct pevent *pevent, int id, | 624 | int pevent_register_event_handler(struct pevent *pevent, int id, |
625 | const char *sys_name, const char *event_name, | 625 | const char *sys_name, const char *event_name, |
626 | pevent_event_handler_func func, void *context); | 626 | pevent_event_handler_func func, void *context); |
627 | int pevent_unregister_event_handler(struct pevent *pevent, int id, | ||
628 | const char *sys_name, const char *event_name, | ||
629 | pevent_event_handler_func func, void *context); | ||
627 | int pevent_register_print_function(struct pevent *pevent, | 630 | int pevent_register_print_function(struct pevent *pevent, |
628 | pevent_func_handler func, | 631 | pevent_func_handler func, |
629 | enum pevent_func_arg_type ret_type, | 632 | enum pevent_func_arg_type ret_type, |
630 | char *name, ...); | 633 | char *name, ...); |
634 | int pevent_unregister_print_function(struct pevent *pevent, | ||
635 | pevent_func_handler func, char *name); | ||
631 | 636 | ||
632 | struct format_field *pevent_find_common_field(struct event_format *event, const char *name); | 637 | struct format_field *pevent_find_common_field(struct event_format *event, const char *name); |
633 | struct format_field *pevent_find_field(struct event_format *event, const char *name); | 638 | struct format_field *pevent_find_field(struct event_format *event, const char *name); |
diff --git a/tools/lib/traceevent/plugin_cfg80211.c b/tools/lib/traceevent/plugin_cfg80211.c index 57e98221db20..c066b25905f8 100644 --- a/tools/lib/traceevent/plugin_cfg80211.c +++ b/tools/lib/traceevent/plugin_cfg80211.c | |||
@@ -22,3 +22,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
22 | PEVENT_FUNC_ARG_VOID); | 22 | PEVENT_FUNC_ARG_VOID); |
23 | return 0; | 23 | return 0; |
24 | } | 24 | } |
25 | |||
26 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
27 | { | ||
28 | pevent_unregister_print_function(pevent, process___le16_to_cpup, | ||
29 | "__le16_to_cpup"); | ||
30 | } | ||
diff --git a/tools/lib/traceevent/plugin_function.c b/tools/lib/traceevent/plugin_function.c index 39461485f9a7..80ba4ff1fe84 100644 --- a/tools/lib/traceevent/plugin_function.c +++ b/tools/lib/traceevent/plugin_function.c | |||
@@ -148,6 +148,9 @@ void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | |||
148 | { | 148 | { |
149 | int i, x; | 149 | int i, x; |
150 | 150 | ||
151 | pevent_unregister_event_handler(pevent, -1, "ftrace", "function", | ||
152 | function_handler, NULL); | ||
153 | |||
151 | for (i = 0; i <= cpus; i++) { | 154 | for (i = 0; i <= cpus; i++) { |
152 | for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) | 155 | for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) |
153 | free(fstack[i].stack[x]); | 156 | free(fstack[i].stack[x]); |
diff --git a/tools/lib/traceevent/plugin_hrtimer.c b/tools/lib/traceevent/plugin_hrtimer.c index 0b0ebf30aa44..12bf14cc1152 100644 --- a/tools/lib/traceevent/plugin_hrtimer.c +++ b/tools/lib/traceevent/plugin_hrtimer.c | |||
@@ -76,3 +76,13 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
76 | timer_start_handler, NULL); | 76 | timer_start_handler, NULL); |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | |||
80 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
81 | { | ||
82 | pevent_unregister_event_handler(pevent, -1, | ||
83 | "timer", "hrtimer_expire_entry", | ||
84 | timer_expire_handler, NULL); | ||
85 | |||
86 | pevent_unregister_event_handler(pevent, -1, "timer", "hrtimer_start", | ||
87 | timer_start_handler, NULL); | ||
88 | } | ||
diff --git a/tools/lib/traceevent/plugin_jbd2.c b/tools/lib/traceevent/plugin_jbd2.c index 2f93f81f0bac..0db714c721be 100644 --- a/tools/lib/traceevent/plugin_jbd2.c +++ b/tools/lib/traceevent/plugin_jbd2.c | |||
@@ -66,3 +66,12 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
66 | PEVENT_FUNC_ARG_VOID); | 66 | PEVENT_FUNC_ARG_VOID); |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | |||
70 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
71 | { | ||
72 | pevent_unregister_print_function(pevent, process_jbd2_dev_to_name, | ||
73 | "jbd2_dev_to_name"); | ||
74 | |||
75 | pevent_unregister_print_function(pevent, process_jiffies_to_msecs, | ||
76 | "jiffies_to_msecs"); | ||
77 | } | ||
diff --git a/tools/lib/traceevent/plugin_kmem.c b/tools/lib/traceevent/plugin_kmem.c index 7115c8037ea8..70650ff48d78 100644 --- a/tools/lib/traceevent/plugin_kmem.c +++ b/tools/lib/traceevent/plugin_kmem.c | |||
@@ -70,3 +70,25 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
70 | call_site_handler, NULL); | 70 | call_site_handler, NULL); |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | |||
74 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
75 | { | ||
76 | pevent_unregister_event_handler(pevent, -1, "kmem", "kfree", | ||
77 | call_site_handler, NULL); | ||
78 | |||
79 | pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc", | ||
80 | call_site_handler, NULL); | ||
81 | |||
82 | pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node", | ||
83 | call_site_handler, NULL); | ||
84 | |||
85 | pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc", | ||
86 | call_site_handler, NULL); | ||
87 | |||
88 | pevent_unregister_event_handler(pevent, -1, "kmem", | ||
89 | "kmem_cache_alloc_node", | ||
90 | call_site_handler, NULL); | ||
91 | |||
92 | pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free", | ||
93 | call_site_handler, NULL); | ||
94 | } | ||
diff --git a/tools/lib/traceevent/plugin_kvm.c b/tools/lib/traceevent/plugin_kvm.c index a0e282c6b967..9e0e8c61b43b 100644 --- a/tools/lib/traceevent/plugin_kvm.c +++ b/tools/lib/traceevent/plugin_kvm.c | |||
@@ -434,3 +434,32 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
434 | PEVENT_FUNC_ARG_VOID); | 434 | PEVENT_FUNC_ARG_VOID); |
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | |||
438 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
439 | { | ||
440 | pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_exit", | ||
441 | kvm_exit_handler, NULL); | ||
442 | |||
443 | pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_emulate_insn", | ||
444 | kvm_emulate_insn_handler, NULL); | ||
445 | |||
446 | pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page", | ||
447 | kvm_mmu_get_page_handler, NULL); | ||
448 | |||
449 | pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page", | ||
450 | kvm_mmu_print_role, NULL); | ||
451 | |||
452 | pevent_unregister_event_handler(pevent, -1, | ||
453 | "kvmmmu", "kvm_mmu_unsync_page", | ||
454 | kvm_mmu_print_role, NULL); | ||
455 | |||
456 | pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page", | ||
457 | kvm_mmu_print_role, NULL); | ||
458 | |||
459 | pevent_unregister_event_handler(pevent, -1, "kvmmmu", | ||
460 | "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, | ||
461 | NULL); | ||
462 | |||
463 | pevent_unregister_print_function(pevent, process_is_writable_pte, | ||
464 | "is_writable_pte"); | ||
465 | } | ||
diff --git a/tools/lib/traceevent/plugin_mac80211.c b/tools/lib/traceevent/plugin_mac80211.c index 558a3b91c046..7e15a0f1c2fd 100644 --- a/tools/lib/traceevent/plugin_mac80211.c +++ b/tools/lib/traceevent/plugin_mac80211.c | |||
@@ -93,3 +93,10 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
93 | drv_bss_info_changed, NULL); | 93 | drv_bss_info_changed, NULL); |
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | |||
97 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
98 | { | ||
99 | pevent_unregister_event_handler(pevent, -1, "mac80211", | ||
100 | "drv_bss_info_changed", | ||
101 | drv_bss_info_changed, NULL); | ||
102 | } | ||
diff --git a/tools/lib/traceevent/plugin_sched_switch.c b/tools/lib/traceevent/plugin_sched_switch.c index fea3724aa24f..f1ce60065258 100644 --- a/tools/lib/traceevent/plugin_sched_switch.c +++ b/tools/lib/traceevent/plugin_sched_switch.c | |||
@@ -146,3 +146,15 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
146 | sched_wakeup_handler, NULL); | 146 | sched_wakeup_handler, NULL); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | |||
150 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
151 | { | ||
152 | pevent_unregister_event_handler(pevent, -1, "sched", "sched_switch", | ||
153 | sched_switch_handler, NULL); | ||
154 | |||
155 | pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup", | ||
156 | sched_wakeup_handler, NULL); | ||
157 | |||
158 | pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new", | ||
159 | sched_wakeup_handler, NULL); | ||
160 | } | ||
diff --git a/tools/lib/traceevent/plugin_scsi.c b/tools/lib/traceevent/plugin_scsi.c index 7ef16cc96562..eda326fc8620 100644 --- a/tools/lib/traceevent/plugin_scsi.c +++ b/tools/lib/traceevent/plugin_scsi.c | |||
@@ -421,3 +421,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
421 | PEVENT_FUNC_ARG_VOID); | 421 | PEVENT_FUNC_ARG_VOID); |
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | |||
425 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
426 | { | ||
427 | pevent_unregister_print_function(pevent, process_scsi_trace_parse_cdb, | ||
428 | "scsi_trace_parse_cdb"); | ||
429 | } | ||
diff --git a/tools/lib/traceevent/plugin_xen.c b/tools/lib/traceevent/plugin_xen.c index e7794298f3a9..3a413eaada68 100644 --- a/tools/lib/traceevent/plugin_xen.c +++ b/tools/lib/traceevent/plugin_xen.c | |||
@@ -128,3 +128,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
128 | PEVENT_FUNC_ARG_VOID); | 128 | PEVENT_FUNC_ARG_VOID); |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | |||
132 | void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) | ||
133 | { | ||
134 | pevent_unregister_print_function(pevent, process_xen_hypercall_name, | ||
135 | "xen_hypercall_name"); | ||
136 | } | ||
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index eefb9fb0c02f..cb2e5868c8e8 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -75,6 +75,12 @@ clean: | |||
75 | $(make) | 75 | $(make) |
76 | 76 | ||
77 | # | 77 | # |
78 | # The build-test target is not really parallel, don't print the jobs info: | ||
79 | # | ||
80 | build-test: | ||
81 | @$(MAKE) -f tests/make --no-print-directory | ||
82 | |||
83 | # | ||
78 | # All other targets get passed through: | 84 | # All other targets get passed through: |
79 | # | 85 | # |
80 | %: | 86 | %: |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 43ff33d0007b..78948882e3de 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -59,7 +59,7 @@ static struct { | |||
59 | struct perf_probe_event events[MAX_PROBES]; | 59 | struct perf_probe_event events[MAX_PROBES]; |
60 | struct strlist *dellist; | 60 | struct strlist *dellist; |
61 | struct line_range line_range; | 61 | struct line_range line_range; |
62 | const char *target; | 62 | char *target; |
63 | int max_probe_points; | 63 | int max_probe_points; |
64 | struct strfilter *filter; | 64 | struct strfilter *filter; |
65 | } params; | 65 | } params; |
@@ -98,7 +98,10 @@ static int set_target(const char *ptr) | |||
98 | * short module name. | 98 | * short module name. |
99 | */ | 99 | */ |
100 | if (!params.target && ptr && *ptr == '/') { | 100 | if (!params.target && ptr && *ptr == '/') { |
101 | params.target = ptr; | 101 | params.target = strdup(ptr); |
102 | if (!params.target) | ||
103 | return -ENOMEM; | ||
104 | |||
102 | found = 1; | 105 | found = 1; |
103 | buf = ptr + (strlen(ptr) - 3); | 106 | buf = ptr + (strlen(ptr) - 3); |
104 | 107 | ||
@@ -116,6 +119,9 @@ static int parse_probe_event_argv(int argc, const char **argv) | |||
116 | char *buf; | 119 | char *buf; |
117 | 120 | ||
118 | found_target = set_target(argv[0]); | 121 | found_target = set_target(argv[0]); |
122 | if (found_target < 0) | ||
123 | return found_target; | ||
124 | |||
119 | if (found_target && argc == 1) | 125 | if (found_target && argc == 1) |
120 | return 0; | 126 | return 0; |
121 | 127 | ||
@@ -217,7 +223,6 @@ static int opt_show_lines(const struct option *opt __maybe_unused, | |||
217 | 223 | ||
218 | params.show_lines = true; | 224 | params.show_lines = true; |
219 | ret = parse_line_range_desc(str, ¶ms.line_range); | 225 | ret = parse_line_range_desc(str, ¶ms.line_range); |
220 | INIT_LIST_HEAD(¶ms.line_range.line_list); | ||
221 | 226 | ||
222 | return ret; | 227 | return ret; |
223 | } | 228 | } |
@@ -263,7 +268,28 @@ static int opt_set_filter(const struct option *opt __maybe_unused, | |||
263 | return 0; | 268 | return 0; |
264 | } | 269 | } |
265 | 270 | ||
266 | int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | 271 | static void init_params(void) |
272 | { | ||
273 | line_range__init(¶ms.line_range); | ||
274 | } | ||
275 | |||
276 | static void cleanup_params(void) | ||
277 | { | ||
278 | int i; | ||
279 | |||
280 | for (i = 0; i < params.nevents; i++) | ||
281 | clear_perf_probe_event(params.events + i); | ||
282 | if (params.dellist) | ||
283 | strlist__delete(params.dellist); | ||
284 | line_range__clear(¶ms.line_range); | ||
285 | free(params.target); | ||
286 | if (params.filter) | ||
287 | strfilter__delete(params.filter); | ||
288 | memset(¶ms, 0, sizeof(params)); | ||
289 | } | ||
290 | |||
291 | static int | ||
292 | __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | ||
267 | { | 293 | { |
268 | const char * const probe_usage[] = { | 294 | const char * const probe_usage[] = { |
269 | "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", | 295 | "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", |
@@ -417,6 +443,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
417 | ret = show_available_funcs(params.target, params.filter, | 443 | ret = show_available_funcs(params.target, params.filter, |
418 | params.uprobes); | 444 | params.uprobes); |
419 | strfilter__delete(params.filter); | 445 | strfilter__delete(params.filter); |
446 | params.filter = NULL; | ||
420 | if (ret < 0) | 447 | if (ret < 0) |
421 | pr_err(" Error: Failed to show functions." | 448 | pr_err(" Error: Failed to show functions." |
422 | " (%d)\n", ret); | 449 | " (%d)\n", ret); |
@@ -456,6 +483,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
456 | params.filter, | 483 | params.filter, |
457 | params.show_ext_vars); | 484 | params.show_ext_vars); |
458 | strfilter__delete(params.filter); | 485 | strfilter__delete(params.filter); |
486 | params.filter = NULL; | ||
459 | if (ret < 0) | 487 | if (ret < 0) |
460 | pr_err(" Error: Failed to show vars. (%d)\n", ret); | 488 | pr_err(" Error: Failed to show vars. (%d)\n", ret); |
461 | return ret; | 489 | return ret; |
@@ -464,7 +492,6 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
464 | 492 | ||
465 | if (params.dellist) { | 493 | if (params.dellist) { |
466 | ret = del_perf_probe_events(params.dellist); | 494 | ret = del_perf_probe_events(params.dellist); |
467 | strlist__delete(params.dellist); | ||
468 | if (ret < 0) { | 495 | if (ret < 0) { |
469 | pr_err(" Error: Failed to delete events. (%d)\n", ret); | 496 | pr_err(" Error: Failed to delete events. (%d)\n", ret); |
470 | return ret; | 497 | return ret; |
@@ -483,3 +510,14 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
483 | } | 510 | } |
484 | return 0; | 511 | return 0; |
485 | } | 512 | } |
513 | |||
514 | int cmd_probe(int argc, const char **argv, const char *prefix) | ||
515 | { | ||
516 | int ret; | ||
517 | |||
518 | init_params(); | ||
519 | ret = __cmd_probe(argc, argv, prefix); | ||
520 | cleanup_params(); | ||
521 | |||
522 | return ret; | ||
523 | } | ||
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9eb4f57f8663..8d9db454f1a9 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <errno.h> | 15 | #include <errno.h> |
16 | #include <math.h> | 16 | #include <math.h> |
17 | 17 | ||
18 | #include "asm/bug.h" | ||
19 | |||
18 | #include "hist.h" | 20 | #include "hist.h" |
19 | #include "util.h" | 21 | #include "util.h" |
20 | #include "sort.h" | 22 | #include "sort.h" |
@@ -358,19 +360,14 @@ append_chain_children(struct callchain_node *root, | |||
358 | /* lookup in childrens */ | 360 | /* lookup in childrens */ |
359 | while (*p) { | 361 | while (*p) { |
360 | s64 ret; | 362 | s64 ret; |
361 | struct callchain_list *cnode; | ||
362 | 363 | ||
363 | parent = *p; | 364 | parent = *p; |
364 | rnode = rb_entry(parent, struct callchain_node, rb_node_in); | 365 | rnode = rb_entry(parent, struct callchain_node, rb_node_in); |
365 | cnode = list_first_entry(&rnode->val, struct callchain_list, | ||
366 | list); | ||
367 | 366 | ||
368 | /* just check first entry */ | 367 | /* If at least first entry matches, rely to children */ |
369 | ret = match_chain(node, cnode); | 368 | ret = append_chain(rnode, cursor, period); |
370 | if (ret == 0) { | 369 | if (ret == 0) |
371 | append_chain(rnode, cursor, period); | ||
372 | goto inc_children_hit; | 370 | goto inc_children_hit; |
373 | } | ||
374 | 371 | ||
375 | if (ret < 0) | 372 | if (ret < 0) |
376 | p = &parent->rb_left; | 373 | p = &parent->rb_left; |
@@ -391,11 +388,11 @@ append_chain(struct callchain_node *root, | |||
391 | struct callchain_cursor *cursor, | 388 | struct callchain_cursor *cursor, |
392 | u64 period) | 389 | u64 period) |
393 | { | 390 | { |
394 | struct callchain_cursor_node *curr_snap = cursor->curr; | ||
395 | struct callchain_list *cnode; | 391 | struct callchain_list *cnode; |
396 | u64 start = cursor->pos; | 392 | u64 start = cursor->pos; |
397 | bool found = false; | 393 | bool found = false; |
398 | u64 matches; | 394 | u64 matches; |
395 | int cmp = 0; | ||
399 | 396 | ||
400 | /* | 397 | /* |
401 | * Lookup in the current node | 398 | * Lookup in the current node |
@@ -410,7 +407,8 @@ append_chain(struct callchain_node *root, | |||
410 | if (!node) | 407 | if (!node) |
411 | break; | 408 | break; |
412 | 409 | ||
413 | if (match_chain(node, cnode) != 0) | 410 | cmp = match_chain(node, cnode); |
411 | if (cmp) | ||
414 | break; | 412 | break; |
415 | 413 | ||
416 | found = true; | 414 | found = true; |
@@ -420,9 +418,8 @@ append_chain(struct callchain_node *root, | |||
420 | 418 | ||
421 | /* matches not, relay no the parent */ | 419 | /* matches not, relay no the parent */ |
422 | if (!found) { | 420 | if (!found) { |
423 | cursor->curr = curr_snap; | 421 | WARN_ONCE(!cmp, "Chain comparison error\n"); |
424 | cursor->pos = start; | 422 | return cmp; |
425 | return -1; | ||
426 | } | 423 | } |
427 | 424 | ||
428 | matches = cursor->pos - start; | 425 | matches = cursor->pos - start; |
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index 67d1e404c0cb..f9e777629e21 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -94,19 +94,20 @@ struct comm *comm__new(const char *str, u64 timestamp) | |||
94 | return comm; | 94 | return comm; |
95 | } | 95 | } |
96 | 96 | ||
97 | void comm__override(struct comm *comm, const char *str, u64 timestamp) | 97 | int comm__override(struct comm *comm, const char *str, u64 timestamp) |
98 | { | 98 | { |
99 | struct comm_str *old = comm->comm_str; | 99 | struct comm_str *new, *old = comm->comm_str; |
100 | 100 | ||
101 | comm->comm_str = comm_str__findnew(str, &comm_str_root); | 101 | new = comm_str__findnew(str, &comm_str_root); |
102 | if (!comm->comm_str) { | 102 | if (!new) |
103 | comm->comm_str = old; | 103 | return -ENOMEM; |
104 | return; | ||
105 | } | ||
106 | 104 | ||
107 | comm->start = timestamp; | 105 | comm_str__get(new); |
108 | comm_str__get(comm->comm_str); | ||
109 | comm_str__put(old); | 106 | comm_str__put(old); |
107 | comm->comm_str = new; | ||
108 | comm->start = timestamp; | ||
109 | |||
110 | return 0; | ||
110 | } | 111 | } |
111 | 112 | ||
112 | void comm__free(struct comm *comm) | 113 | void comm__free(struct comm *comm) |
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h index 7a86e5656710..fac5bd51befc 100644 --- a/tools/perf/util/comm.h +++ b/tools/perf/util/comm.h | |||
@@ -16,6 +16,6 @@ struct comm { | |||
16 | void comm__free(struct comm *comm); | 16 | void comm__free(struct comm *comm); |
17 | struct comm *comm__new(const char *str, u64 timestamp); | 17 | struct comm *comm__new(const char *str, u64 timestamp); |
18 | const char *comm__str(const struct comm *comm); | 18 | const char *comm__str(const struct comm *comm); |
19 | void comm__override(struct comm *comm, const char *str, u64 timestamp); | 19 | int comm__override(struct comm *comm, const char *str, u64 timestamp); |
20 | 20 | ||
21 | #endif /* __PERF_COMM_H */ | 21 | #endif /* __PERF_COMM_H */ |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a4ee6b4a840f..a8a9b6cd93a8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -72,6 +72,7 @@ static int e_snprintf(char *str, size_t size, const char *format, ...) | |||
72 | static char *synthesize_perf_probe_point(struct perf_probe_point *pp); | 72 | static char *synthesize_perf_probe_point(struct perf_probe_point *pp); |
73 | static int convert_name_to_addr(struct perf_probe_event *pev, | 73 | static int convert_name_to_addr(struct perf_probe_event *pev, |
74 | const char *exec); | 74 | const char *exec); |
75 | static void clear_probe_trace_event(struct probe_trace_event *tev); | ||
75 | static struct machine machine; | 76 | static struct machine machine; |
76 | 77 | ||
77 | /* Initialize symbol maps and path of vmlinux/modules */ | 78 | /* Initialize symbol maps and path of vmlinux/modules */ |
@@ -172,54 +173,6 @@ const char *kernel_get_module_path(const char *module) | |||
172 | return (dso) ? dso->long_name : NULL; | 173 | return (dso) ? dso->long_name : NULL; |
173 | } | 174 | } |
174 | 175 | ||
175 | #ifdef HAVE_DWARF_SUPPORT | ||
176 | /* Copied from unwind.c */ | ||
177 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
178 | GElf_Shdr *shp, const char *name) | ||
179 | { | ||
180 | Elf_Scn *sec = NULL; | ||
181 | |||
182 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
183 | char *str; | ||
184 | |||
185 | gelf_getshdr(sec, shp); | ||
186 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
187 | if (!strcmp(name, str)) | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | return sec; | ||
192 | } | ||
193 | |||
194 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
195 | { | ||
196 | Elf *elf; | ||
197 | GElf_Ehdr ehdr; | ||
198 | GElf_Shdr shdr; | ||
199 | int fd, ret = -ENOENT; | ||
200 | |||
201 | fd = open(exec, O_RDONLY); | ||
202 | if (fd < 0) | ||
203 | return -errno; | ||
204 | |||
205 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
206 | if (elf == NULL) | ||
207 | return -EINVAL; | ||
208 | |||
209 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
210 | goto out; | ||
211 | |||
212 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text")) | ||
213 | goto out; | ||
214 | |||
215 | *address = shdr.sh_addr - shdr.sh_offset; | ||
216 | ret = 0; | ||
217 | out: | ||
218 | elf_end(elf); | ||
219 | return ret; | ||
220 | } | ||
221 | #endif | ||
222 | |||
223 | static int init_user_exec(void) | 176 | static int init_user_exec(void) |
224 | { | 177 | { |
225 | int ret = 0; | 178 | int ret = 0; |
@@ -340,6 +293,34 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | |||
340 | return 0; | 293 | return 0; |
341 | } | 294 | } |
342 | 295 | ||
296 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
297 | { | ||
298 | Elf *elf; | ||
299 | GElf_Ehdr ehdr; | ||
300 | GElf_Shdr shdr; | ||
301 | int fd, ret = -ENOENT; | ||
302 | |||
303 | fd = open(exec, O_RDONLY); | ||
304 | if (fd < 0) | ||
305 | return -errno; | ||
306 | |||
307 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
308 | if (elf == NULL) | ||
309 | return -EINVAL; | ||
310 | |||
311 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
312 | goto out; | ||
313 | |||
314 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL)) | ||
315 | goto out; | ||
316 | |||
317 | *address = shdr.sh_addr - shdr.sh_offset; | ||
318 | ret = 0; | ||
319 | out: | ||
320 | elf_end(elf); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
343 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | 324 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, |
344 | int ntevs, const char *exec) | 325 | int ntevs, const char *exec) |
345 | { | 326 | { |
@@ -407,6 +388,14 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, | |||
407 | return ret; | 388 | return ret; |
408 | } | 389 | } |
409 | 390 | ||
391 | static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) | ||
392 | { | ||
393 | int i; | ||
394 | |||
395 | for (i = 0; i < ntevs; i++) | ||
396 | clear_probe_trace_event(tevs + i); | ||
397 | } | ||
398 | |||
410 | /* Try to find perf_probe_event with debuginfo */ | 399 | /* Try to find perf_probe_event with debuginfo */ |
411 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | 400 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, |
412 | struct probe_trace_event **tevs, | 401 | struct probe_trace_event **tevs, |
@@ -442,6 +431,10 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
442 | ret = add_module_to_probe_trace_events(*tevs, | 431 | ret = add_module_to_probe_trace_events(*tevs, |
443 | ntevs, target); | 432 | ntevs, target); |
444 | } | 433 | } |
434 | if (ret < 0) { | ||
435 | clear_probe_trace_events(*tevs, ntevs); | ||
436 | zfree(tevs); | ||
437 | } | ||
445 | return ret < 0 ? ret : ntevs; | 438 | return ret < 0 ? ret : ntevs; |
446 | } | 439 | } |
447 | 440 | ||
@@ -781,6 +774,28 @@ int show_available_vars(struct perf_probe_event *pevs __maybe_unused, | |||
781 | } | 774 | } |
782 | #endif | 775 | #endif |
783 | 776 | ||
777 | void line_range__clear(struct line_range *lr) | ||
778 | { | ||
779 | struct line_node *ln; | ||
780 | |||
781 | free(lr->function); | ||
782 | free(lr->file); | ||
783 | free(lr->path); | ||
784 | free(lr->comp_dir); | ||
785 | while (!list_empty(&lr->line_list)) { | ||
786 | ln = list_first_entry(&lr->line_list, struct line_node, list); | ||
787 | list_del(&ln->list); | ||
788 | free(ln); | ||
789 | } | ||
790 | memset(lr, 0, sizeof(*lr)); | ||
791 | } | ||
792 | |||
793 | void line_range__init(struct line_range *lr) | ||
794 | { | ||
795 | memset(lr, 0, sizeof(*lr)); | ||
796 | INIT_LIST_HEAD(&lr->line_list); | ||
797 | } | ||
798 | |||
784 | static int parse_line_num(char **ptr, int *val, const char *what) | 799 | static int parse_line_num(char **ptr, int *val, const char *what) |
785 | { | 800 | { |
786 | const char *start = *ptr; | 801 | const char *start = *ptr; |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index d481c46e0796..fcaf7273e85a 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -120,6 +120,12 @@ extern void clear_perf_probe_event(struct perf_probe_event *pev); | |||
120 | /* Command string to line-range */ | 120 | /* Command string to line-range */ |
121 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); | 121 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); |
122 | 122 | ||
123 | /* Release line range members */ | ||
124 | extern void line_range__clear(struct line_range *lr); | ||
125 | |||
126 | /* Initialize line range */ | ||
127 | extern void line_range__init(struct line_range *lr); | ||
128 | |||
123 | /* Internal use: Return kernel/module path */ | 129 | /* Internal use: Return kernel/module path */ |
124 | extern const char *kernel_get_module_path(const char *module); | 130 | extern const char *kernel_get_module_path(const char *module); |
125 | 131 | ||
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 4b0a127a4d3b..759456728703 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -136,9 +136,8 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) | |||
136 | return -1; | 136 | return -1; |
137 | } | 137 | } |
138 | 138 | ||
139 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | 139 | Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, |
140 | GElf_Shdr *shp, const char *name, | 140 | GElf_Shdr *shp, const char *name, size_t *idx) |
141 | size_t *idx) | ||
142 | { | 141 | { |
143 | Elf_Scn *sec = NULL; | 142 | Elf_Scn *sec = NULL; |
144 | size_t cnt = 1; | 143 | size_t cnt = 1; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index cbd680361806..fffe2888a1c7 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -52,6 +52,11 @@ static inline char *bfd_demangle(void __maybe_unused *v, | |||
52 | # define PERF_ELF_C_READ_MMAP ELF_C_READ | 52 | # define PERF_ELF_C_READ_MMAP ELF_C_READ |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #ifdef HAVE_LIBELF_SUPPORT | ||
56 | extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
57 | GElf_Shdr *shp, const char *name, size_t *idx); | ||
58 | #endif | ||
59 | |||
55 | #ifndef DMGL_PARAMS | 60 | #ifndef DMGL_PARAMS |
56 | #define DMGL_PARAMS (1 << 0) /* Include function args */ | 61 | #define DMGL_PARAMS (1 << 0) /* Include function args */ |
57 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ | 62 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index e3948612543e..0358882c8910 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -66,10 +66,13 @@ struct comm *thread__comm(const struct thread *thread) | |||
66 | int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) | 66 | int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) |
67 | { | 67 | { |
68 | struct comm *new, *curr = thread__comm(thread); | 68 | struct comm *new, *curr = thread__comm(thread); |
69 | int err; | ||
69 | 70 | ||
70 | /* Override latest entry if it had no specific time coverage */ | 71 | /* Override latest entry if it had no specific time coverage */ |
71 | if (!curr->start) { | 72 | if (!curr->start) { |
72 | comm__override(curr, str, timestamp); | 73 | err = comm__override(curr, str, timestamp); |
74 | if (err) | ||
75 | return err; | ||
73 | } else { | 76 | } else { |
74 | new = comm__new(str, timestamp); | 77 | new = comm__new(str, timestamp); |
75 | if (!new) | 78 | if (!new) |
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 416f22bf3693..742f23bf35ff 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "session.h" | 28 | #include "session.h" |
29 | #include "perf_regs.h" | 29 | #include "perf_regs.h" |
30 | #include "unwind.h" | 30 | #include "unwind.h" |
31 | #include "symbol.h" | ||
31 | #include "util.h" | 32 | #include "util.h" |
32 | 33 | ||
33 | extern int | 34 | extern int |
@@ -158,23 +159,6 @@ static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val, | |||
158 | __v; \ | 159 | __v; \ |
159 | }) | 160 | }) |
160 | 161 | ||
161 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
162 | GElf_Shdr *shp, const char *name) | ||
163 | { | ||
164 | Elf_Scn *sec = NULL; | ||
165 | |||
166 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
167 | char *str; | ||
168 | |||
169 | gelf_getshdr(sec, shp); | ||
170 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
171 | if (!strcmp(name, str)) | ||
172 | break; | ||
173 | } | ||
174 | |||
175 | return sec; | ||
176 | } | ||
177 | |||
178 | static u64 elf_section_offset(int fd, const char *name) | 162 | static u64 elf_section_offset(int fd, const char *name) |
179 | { | 163 | { |
180 | Elf *elf; | 164 | Elf *elf; |
@@ -190,7 +174,7 @@ static u64 elf_section_offset(int fd, const char *name) | |||
190 | if (gelf_getehdr(elf, &ehdr) == NULL) | 174 | if (gelf_getehdr(elf, &ehdr) == NULL) |
191 | break; | 175 | break; |
192 | 176 | ||
193 | if (!elf_section_by_name(elf, &ehdr, &shdr, name)) | 177 | if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL)) |
194 | break; | 178 | break; |
195 | 179 | ||
196 | offset = shdr.sh_offset; | 180 | offset = shdr.sh_offset; |