diff options
| author | Ingo Molnar <mingo@kernel.org> | 2012-09-08 07:26:02 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2012-09-08 07:26:02 -0400 |
| commit | ef34eb4da3eb62a1511592adf7c76d74faca0b14 (patch) | |
| tree | 7f28887cf8c5d7059416769e152e79f68ce32830 /tools | |
| parent | 479d875835a49e849683743ec50c30b6a429696b (diff) | |
| parent | b155a09015135cf59ada8d48109ccbd9891c1b42 (diff) | |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
* Fix build for another rbtree.c change, from Adrian Hunter.
* Fixes for perf to build on Android, from Irina Tirdea.
* Make 'perf diff' command work with evsel hists, from Jiri Olsa.
* Use the only field_sep var that is set up: symbol_conf.field_sep,
fix from Jiri Olsa.
* .gitignore compiled python binaries, from Namhyung Kim.
* Get rid of die() in more libtraceevent places, from 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 | 86 | ||||
| -rw-r--r-- | tools/lib/traceevent/event-parse.h | 3 | ||||
| -rw-r--r-- | tools/perf/.gitignore | 2 | ||||
| -rw-r--r-- | tools/perf/Documentation/perf-diff.txt | 3 | ||||
| -rw-r--r-- | tools/perf/Makefile | 8 | ||||
| -rw-r--r-- | tools/perf/builtin-diff.c | 93 | ||||
| -rw-r--r-- | tools/perf/config/feature-tests.mak | 14 | ||||
| -rw-r--r-- | tools/perf/perf.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/annotate.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/dso-test-data.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/evsel.h | 7 | ||||
| -rw-r--r-- | tools/perf/util/help.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/include/linux/rbtree.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 4 | ||||
| -rw-r--r-- | tools/perf/util/sort.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/sort.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 3 | ||||
| -rw-r--r-- | tools/perf/util/top.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/util.c | 6 |
19 files changed, 180 insertions, 63 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b5b4d806ffa2..f4190b5764de 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -3889,8 +3889,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3889 | goto cont_process; | 3889 | goto cont_process; |
| 3890 | case '*': | 3890 | case '*': |
| 3891 | /* The argument is the length. */ | 3891 | /* The argument is the length. */ |
| 3892 | if (!arg) | 3892 | if (!arg) { |
| 3893 | die("no argument match"); | 3893 | do_warning("no argument match"); |
| 3894 | event->flags |= EVENT_FL_FAILED; | ||
| 3895 | goto out_failed; | ||
| 3896 | } | ||
| 3894 | len_arg = eval_num_arg(data, size, event, arg); | 3897 | len_arg = eval_num_arg(data, size, event, arg); |
| 3895 | len_as_arg = 1; | 3898 | len_as_arg = 1; |
| 3896 | arg = arg->next; | 3899 | arg = arg->next; |
| @@ -3923,15 +3926,21 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3923 | case 'x': | 3926 | case 'x': |
| 3924 | case 'X': | 3927 | case 'X': |
| 3925 | case 'u': | 3928 | case 'u': |
| 3926 | if (!arg) | 3929 | if (!arg) { |
| 3927 | die("no argument match"); | 3930 | do_warning("no argument match"); |
| 3931 | event->flags |= EVENT_FL_FAILED; | ||
| 3932 | goto out_failed; | ||
| 3933 | } | ||
| 3928 | 3934 | ||
| 3929 | len = ((unsigned long)ptr + 1) - | 3935 | len = ((unsigned long)ptr + 1) - |
| 3930 | (unsigned long)saveptr; | 3936 | (unsigned long)saveptr; |
| 3931 | 3937 | ||
| 3932 | /* should never happen */ | 3938 | /* should never happen */ |
| 3933 | if (len > 31) | 3939 | if (len > 31) { |
| 3934 | die("bad format!"); | 3940 | do_warning("bad format!"); |
| 3941 | event->flags |= EVENT_FL_FAILED; | ||
| 3942 | len = 31; | ||
| 3943 | } | ||
| 3935 | 3944 | ||
| 3936 | memcpy(format, saveptr, len); | 3945 | memcpy(format, saveptr, len); |
| 3937 | format[len] = 0; | 3946 | format[len] = 0; |
| @@ -3995,19 +4004,26 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3995 | trace_seq_printf(s, format, (long long)val); | 4004 | trace_seq_printf(s, format, (long long)val); |
| 3996 | break; | 4005 | break; |
| 3997 | default: | 4006 | default: |
| 3998 | die("bad count (%d)", ls); | 4007 | do_warning("bad count (%d)", ls); |
| 4008 | event->flags |= EVENT_FL_FAILED; | ||
| 3999 | } | 4009 | } |
| 4000 | break; | 4010 | break; |
| 4001 | case 's': | 4011 | case 's': |
| 4002 | if (!arg) | 4012 | if (!arg) { |
| 4003 | die("no matching argument"); | 4013 | do_warning("no matching argument"); |
| 4014 | event->flags |= EVENT_FL_FAILED; | ||
| 4015 | goto out_failed; | ||
| 4016 | } | ||
| 4004 | 4017 | ||
| 4005 | len = ((unsigned long)ptr + 1) - | 4018 | len = ((unsigned long)ptr + 1) - |
| 4006 | (unsigned long)saveptr; | 4019 | (unsigned long)saveptr; |
| 4007 | 4020 | ||
| 4008 | /* should never happen */ | 4021 | /* should never happen */ |
| 4009 | if (len > 31) | 4022 | if (len > 31) { |
| 4010 | die("bad format!"); | 4023 | do_warning("bad format!"); |
| 4024 | event->flags |= EVENT_FL_FAILED; | ||
| 4025 | len = 31; | ||
| 4026 | } | ||
| 4011 | 4027 | ||
| 4012 | memcpy(format, saveptr, len); | 4028 | memcpy(format, saveptr, len); |
| 4013 | format[len] = 0; | 4029 | format[len] = 0; |
| @@ -4025,6 +4041,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 4025 | trace_seq_putc(s, *ptr); | 4041 | trace_seq_putc(s, *ptr); |
| 4026 | } | 4042 | } |
| 4027 | 4043 | ||
| 4044 | if (event->flags & EVENT_FL_FAILED) { | ||
| 4045 | out_failed: | ||
| 4046 | trace_seq_printf(s, "[FAILED TO PARSE]"); | ||
| 4047 | } | ||
| 4048 | |||
| 4028 | if (args) { | 4049 | if (args) { |
| 4029 | free_args(args); | 4050 | free_args(args); |
| 4030 | free(bprint_fmt); | 4051 | free(bprint_fmt); |
| @@ -4812,8 +4833,8 @@ int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, | |||
| 4812 | msg = strerror_r(errnum, buf, buflen); | 4833 | msg = strerror_r(errnum, buf, buflen); |
| 4813 | if (msg != buf) { | 4834 | if (msg != buf) { |
| 4814 | size_t len = strlen(msg); | 4835 | size_t len = strlen(msg); |
| 4815 | char *c = mempcpy(buf, msg, min(buflen-1, len)); | 4836 | memcpy(buf, msg, min(buflen - 1, len)); |
| 4816 | *c = '\0'; | 4837 | *(buf + min(buflen - 1, len)) = '\0'; |
| 4817 | } | 4838 | } |
| 4818 | return 0; | 4839 | return 0; |
| 4819 | } | 4840 | } |
| @@ -5059,6 +5080,7 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5059 | struct pevent_func_params *param; | 5080 | struct pevent_func_params *param; |
| 5060 | enum pevent_func_arg_type type; | 5081 | enum pevent_func_arg_type type; |
| 5061 | va_list ap; | 5082 | va_list ap; |
| 5083 | int ret; | ||
| 5062 | 5084 | ||
| 5063 | func_handle = find_func_handler(pevent, name); | 5085 | func_handle = find_func_handler(pevent, name); |
| 5064 | if (func_handle) { | 5086 | if (func_handle) { |
| @@ -5071,14 +5093,21 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5071 | remove_func_handler(pevent, name); | 5093 | remove_func_handler(pevent, name); |
| 5072 | } | 5094 | } |
| 5073 | 5095 | ||
| 5074 | func_handle = malloc_or_die(sizeof(*func_handle)); | 5096 | func_handle = malloc(sizeof(*func_handle)); |
| 5097 | if (!func_handle) { | ||
| 5098 | do_warning("Failed to allocate function handler"); | ||
| 5099 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5100 | } | ||
| 5075 | memset(func_handle, 0, sizeof(*func_handle)); | 5101 | memset(func_handle, 0, sizeof(*func_handle)); |
| 5076 | 5102 | ||
| 5077 | func_handle->ret_type = ret_type; | 5103 | func_handle->ret_type = ret_type; |
| 5078 | func_handle->name = strdup(name); | 5104 | func_handle->name = strdup(name); |
| 5079 | func_handle->func = func; | 5105 | func_handle->func = func; |
| 5080 | if (!func_handle->name) | 5106 | if (!func_handle->name) { |
| 5081 | die("Failed to allocate function name"); | 5107 | do_warning("Failed to allocate function name"); |
| 5108 | free(func_handle); | ||
| 5109 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5110 | } | ||
| 5082 | 5111 | ||
| 5083 | next_param = &(func_handle->params); | 5112 | next_param = &(func_handle->params); |
| 5084 | va_start(ap, name); | 5113 | va_start(ap, name); |
| @@ -5088,11 +5117,17 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5088 | break; | 5117 | break; |
| 5089 | 5118 | ||
| 5090 | if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { | 5119 | if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { |
| 5091 | warning("Invalid argument type %d", type); | 5120 | do_warning("Invalid argument type %d", type); |
| 5121 | ret = PEVENT_ERRNO__INVALID_ARG_TYPE; | ||
| 5092 | goto out_free; | 5122 | goto out_free; |
| 5093 | } | 5123 | } |
| 5094 | 5124 | ||
| 5095 | param = malloc_or_die(sizeof(*param)); | 5125 | param = malloc(sizeof(*param)); |
| 5126 | if (!param) { | ||
| 5127 | do_warning("Failed to allocate function param"); | ||
| 5128 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5129 | goto out_free; | ||
| 5130 | } | ||
| 5096 | param->type = type; | 5131 | param->type = type; |
| 5097 | param->next = NULL; | 5132 | param->next = NULL; |
| 5098 | 5133 | ||
| @@ -5110,7 +5145,7 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5110 | out_free: | 5145 | out_free: |
| 5111 | va_end(ap); | 5146 | va_end(ap); |
| 5112 | free_func_handle(func_handle); | 5147 | free_func_handle(func_handle); |
| 5113 | return -1; | 5148 | return ret; |
| 5114 | } | 5149 | } |
| 5115 | 5150 | ||
| 5116 | /** | 5151 | /** |
| @@ -5162,7 +5197,12 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
| 5162 | 5197 | ||
| 5163 | not_found: | 5198 | not_found: |
| 5164 | /* Save for later use. */ | 5199 | /* Save for later use. */ |
| 5165 | handle = malloc_or_die(sizeof(*handle)); | 5200 | handle = malloc(sizeof(*handle)); |
| 5201 | if (!handle) { | ||
| 5202 | do_warning("Failed to allocate event handler"); | ||
| 5203 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5204 | } | ||
| 5205 | |||
| 5166 | memset(handle, 0, sizeof(*handle)); | 5206 | memset(handle, 0, sizeof(*handle)); |
| 5167 | handle->id = id; | 5207 | handle->id = id; |
| 5168 | if (event_name) | 5208 | if (event_name) |
| @@ -5172,7 +5212,11 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
| 5172 | 5212 | ||
| 5173 | if ((event_name && !handle->event_name) || | 5213 | if ((event_name && !handle->event_name) || |
| 5174 | (sys_name && !handle->sys_name)) { | 5214 | (sys_name && !handle->sys_name)) { |
| 5175 | die("Failed to allocate event/sys name"); | 5215 | do_warning("Failed to allocate event/sys name"); |
| 5216 | free((void *)handle->event_name); | ||
| 5217 | free((void *)handle->sys_name); | ||
| 5218 | free(handle); | ||
| 5219 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5176 | } | 5220 | } |
| 5177 | 5221 | ||
| 5178 | handle->func = func; | 5222 | handle->func = func; |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 863a0bbda7f1..3318963f1c98 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
| @@ -351,7 +351,8 @@ enum pevent_flag { | |||
| 351 | _PE(READ_ID_FAILED, "failed to read event id"), \ | 351 | _PE(READ_ID_FAILED, "failed to read event id"), \ |
| 352 | _PE(READ_FORMAT_FAILED, "failed to read event format"), \ | 352 | _PE(READ_FORMAT_FAILED, "failed to read event format"), \ |
| 353 | _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ | 353 | _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ |
| 354 | _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace") | 354 | _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ |
| 355 | _PE(INVALID_ARG_TYPE, "invalid argument type") | ||
| 355 | 356 | ||
| 356 | #undef _PE | 357 | #undef _PE |
| 357 | #define _PE(__code, __str) PEVENT_ERRNO__ ## __code | 358 | #define _PE(__code, __str) PEVENT_ERRNO__ ## __code |
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 26b823b61aa1..8f8fbc227a46 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore | |||
| @@ -21,3 +21,5 @@ config.mak | |||
| 21 | config.mak.autogen | 21 | config.mak.autogen |
| 22 | *-bison.* | 22 | *-bison.* |
| 23 | *-flex.* | 23 | *-flex.* |
| 24 | *.pyc | ||
| 25 | *.pyo | ||
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 74d7481ed7a6..ab7f667de1b1 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt | |||
| @@ -17,6 +17,9 @@ captured via perf record. | |||
| 17 | 17 | ||
| 18 | If no parameters are passed it will assume perf.data.old and perf.data. | 18 | If no parameters are passed it will assume perf.data.old and perf.data. |
| 19 | 19 | ||
| 20 | The differential profile is displayed only for events matching both | ||
| 21 | specified perf.data files. | ||
| 22 | |||
| 20 | OPTIONS | 23 | OPTIONS |
| 21 | ------- | 24 | ------- |
| 22 | -M:: | 25 | -M:: |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index afd507574902..3eda49215730 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -755,6 +755,14 @@ else | |||
| 755 | endif | 755 | endif |
| 756 | endif | 756 | endif |
| 757 | 757 | ||
| 758 | ifdef NO_BACKTRACE | ||
| 759 | BASIC_CFLAGS += -DNO_BACKTRACE | ||
| 760 | else | ||
| 761 | ifneq ($(call try-cc,$(SOURCE_BACKTRACE),),y) | ||
| 762 | BASIC_CFLAGS += -DNO_BACKTRACE | ||
| 763 | endif | ||
| 764 | endif | ||
| 765 | |||
| 758 | ifdef ASCIIDOC8 | 766 | ifdef ASCIIDOC8 |
| 759 | export ASCIIDOC8 | 767 | export ASCIIDOC8 |
| 760 | endif | 768 | endif |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d29d350fb2b7..e9933fdd256e 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "util/event.h" | 10 | #include "util/event.h" |
| 11 | #include "util/hist.h" | 11 | #include "util/hist.h" |
| 12 | #include "util/evsel.h" | 12 | #include "util/evsel.h" |
| 13 | #include "util/evlist.h" | ||
| 13 | #include "util/session.h" | 14 | #include "util/session.h" |
| 14 | #include "util/tool.h" | 15 | #include "util/tool.h" |
| 15 | #include "util/sort.h" | 16 | #include "util/sort.h" |
| @@ -24,11 +25,6 @@ static char diff__default_sort_order[] = "dso,symbol"; | |||
| 24 | static bool force; | 25 | static bool force; |
| 25 | static bool show_displacement; | 26 | static bool show_displacement; |
| 26 | 27 | ||
| 27 | struct perf_diff { | ||
| 28 | struct perf_tool tool; | ||
| 29 | struct perf_session *session; | ||
| 30 | }; | ||
| 31 | |||
| 32 | static int hists__add_entry(struct hists *self, | 28 | static int hists__add_entry(struct hists *self, |
| 33 | struct addr_location *al, u64 period) | 29 | struct addr_location *al, u64 period) |
| 34 | { | 30 | { |
| @@ -37,14 +33,12 @@ static int hists__add_entry(struct hists *self, | |||
| 37 | return -ENOMEM; | 33 | return -ENOMEM; |
| 38 | } | 34 | } |
| 39 | 35 | ||
| 40 | static int diff__process_sample_event(struct perf_tool *tool, | 36 | static int diff__process_sample_event(struct perf_tool *tool __used, |
| 41 | union perf_event *event, | 37 | union perf_event *event, |
| 42 | struct perf_sample *sample, | 38 | struct perf_sample *sample, |
| 43 | struct perf_evsel *evsel __used, | 39 | struct perf_evsel *evsel, |
| 44 | struct machine *machine) | 40 | struct machine *machine) |
| 45 | { | 41 | { |
| 46 | struct perf_diff *_diff = container_of(tool, struct perf_diff, tool); | ||
| 47 | struct perf_session *session = _diff->session; | ||
| 48 | struct addr_location al; | 42 | struct addr_location al; |
| 49 | 43 | ||
| 50 | if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { | 44 | if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { |
| @@ -56,26 +50,24 @@ static int diff__process_sample_event(struct perf_tool *tool, | |||
| 56 | if (al.filtered || al.sym == NULL) | 50 | if (al.filtered || al.sym == NULL) |
| 57 | return 0; | 51 | return 0; |
| 58 | 52 | ||
| 59 | if (hists__add_entry(&session->hists, &al, sample->period)) { | 53 | if (hists__add_entry(&evsel->hists, &al, sample->period)) { |
| 60 | pr_warning("problem incrementing symbol period, skipping event\n"); | 54 | pr_warning("problem incrementing symbol period, skipping event\n"); |
| 61 | return -1; | 55 | return -1; |
| 62 | } | 56 | } |
| 63 | 57 | ||
| 64 | session->hists.stats.total_period += sample->period; | 58 | evsel->hists.stats.total_period += sample->period; |
| 65 | return 0; | 59 | return 0; |
| 66 | } | 60 | } |
| 67 | 61 | ||
| 68 | static struct perf_diff diff = { | 62 | static struct perf_tool tool = { |
| 69 | .tool = { | 63 | .sample = diff__process_sample_event, |
| 70 | .sample = diff__process_sample_event, | 64 | .mmap = perf_event__process_mmap, |
| 71 | .mmap = perf_event__process_mmap, | 65 | .comm = perf_event__process_comm, |
| 72 | .comm = perf_event__process_comm, | 66 | .exit = perf_event__process_task, |
| 73 | .exit = perf_event__process_task, | 67 | .fork = perf_event__process_task, |
| 74 | .fork = perf_event__process_task, | 68 | .lost = perf_event__process_lost, |
| 75 | .lost = perf_event__process_lost, | 69 | .ordered_samples = true, |
| 76 | .ordered_samples = true, | 70 | .ordering_requires_timestamps = true, |
| 77 | .ordering_requires_timestamps = true, | ||
| 78 | }, | ||
| 79 | }; | 71 | }; |
| 80 | 72 | ||
| 81 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | 73 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, |
| @@ -146,34 +138,71 @@ static void hists__match(struct hists *older, struct hists *newer) | |||
| 146 | } | 138 | } |
| 147 | } | 139 | } |
| 148 | 140 | ||
| 141 | static struct perf_evsel *evsel_match(struct perf_evsel *evsel, | ||
| 142 | struct perf_evlist *evlist) | ||
| 143 | { | ||
| 144 | struct perf_evsel *e; | ||
| 145 | |||
| 146 | list_for_each_entry(e, &evlist->entries, node) | ||
| 147 | if (perf_evsel__match2(evsel, e)) | ||
| 148 | return e; | ||
| 149 | |||
| 150 | return NULL; | ||
| 151 | } | ||
| 152 | |||
| 149 | static int __cmd_diff(void) | 153 | static int __cmd_diff(void) |
| 150 | { | 154 | { |
| 151 | int ret, i; | 155 | int ret, i; |
| 152 | #define older (session[0]) | 156 | #define older (session[0]) |
| 153 | #define newer (session[1]) | 157 | #define newer (session[1]) |
| 154 | struct perf_session *session[2]; | 158 | struct perf_session *session[2]; |
| 159 | struct perf_evlist *evlist_new, *evlist_old; | ||
| 160 | struct perf_evsel *evsel; | ||
| 161 | bool first = true; | ||
| 155 | 162 | ||
| 156 | older = perf_session__new(input_old, O_RDONLY, force, false, | 163 | older = perf_session__new(input_old, O_RDONLY, force, false, |
| 157 | &diff.tool); | 164 | &tool); |
| 158 | newer = perf_session__new(input_new, O_RDONLY, force, false, | 165 | newer = perf_session__new(input_new, O_RDONLY, force, false, |
| 159 | &diff.tool); | 166 | &tool); |
| 160 | if (session[0] == NULL || session[1] == NULL) | 167 | if (session[0] == NULL || session[1] == NULL) |
| 161 | return -ENOMEM; | 168 | return -ENOMEM; |
| 162 | 169 | ||
| 163 | for (i = 0; i < 2; ++i) { | 170 | for (i = 0; i < 2; ++i) { |
| 164 | diff.session = session[i]; | 171 | ret = perf_session__process_events(session[i], &tool); |
| 165 | ret = perf_session__process_events(session[i], &diff.tool); | ||
| 166 | if (ret) | 172 | if (ret) |
| 167 | goto out_delete; | 173 | goto out_delete; |
| 168 | hists__output_resort(&session[i]->hists); | ||
| 169 | } | 174 | } |
| 170 | 175 | ||
| 171 | if (show_displacement) | 176 | evlist_old = older->evlist; |
| 172 | hists__resort_entries(&older->hists); | 177 | evlist_new = newer->evlist; |
| 178 | |||
| 179 | list_for_each_entry(evsel, &evlist_new->entries, node) | ||
| 180 | hists__output_resort(&evsel->hists); | ||
| 181 | |||
| 182 | list_for_each_entry(evsel, &evlist_old->entries, node) { | ||
| 183 | hists__output_resort(&evsel->hists); | ||
| 184 | |||
| 185 | if (show_displacement) | ||
| 186 | hists__resort_entries(&evsel->hists); | ||
| 187 | } | ||
| 188 | |||
| 189 | list_for_each_entry(evsel, &evlist_new->entries, node) { | ||
| 190 | struct perf_evsel *evsel_old; | ||
| 191 | |||
| 192 | evsel_old = evsel_match(evsel, evlist_old); | ||
| 193 | if (!evsel_old) | ||
| 194 | continue; | ||
| 195 | |||
| 196 | fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", | ||
| 197 | perf_evsel__name(evsel)); | ||
| 198 | |||
| 199 | first = false; | ||
| 200 | |||
| 201 | hists__match(&evsel_old->hists, &evsel->hists); | ||
| 202 | hists__fprintf(&evsel->hists, &evsel_old->hists, | ||
| 203 | show_displacement, true, 0, 0, stdout); | ||
| 204 | } | ||
| 173 | 205 | ||
| 174 | hists__match(&older->hists, &newer->hists); | ||
| 175 | hists__fprintf(&newer->hists, &older->hists, | ||
| 176 | show_displacement, true, 0, 0, stdout); | ||
| 177 | out_delete: | 206 | out_delete: |
| 178 | for (i = 0; i < 2; ++i) | 207 | for (i = 0; i < 2; ++i) |
| 179 | perf_session__delete(session[i]); | 208 | perf_session__delete(session[i]); |
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 2f1156a62ab7..116690a669d2 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak | |||
| @@ -179,3 +179,17 @@ int main(void) | |||
| 179 | } | 179 | } |
| 180 | endef | 180 | endef |
| 181 | endif | 181 | endif |
| 182 | |||
| 183 | ifndef NO_BACKTRACE | ||
| 184 | define SOURCE_BACKTRACE | ||
| 185 | #include <execinfo.h> | ||
| 186 | #include <stdio.h> | ||
| 187 | |||
| 188 | int main(void) | ||
| 189 | { | ||
| 190 | backtrace(NULL, 0); | ||
| 191 | backtrace_symbols(NULL, 0); | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | endef | ||
| 195 | endif | ||
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index e7840e500715..fb8578cfa03c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "util/run-command.h" | 14 | #include "util/run-command.h" |
| 15 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
| 16 | #include "util/debugfs.h" | 16 | #include "util/debugfs.h" |
| 17 | #include <pthread.h> | ||
| 17 | 18 | ||
| 18 | const char perf_usage_string[] = | 19 | const char perf_usage_string[] = |
| 19 | "perf [--version] [--help] COMMAND [ARGS]"; | 20 | "perf [--version] [--help] COMMAND [ARGS]"; |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index a6d6bc5d7164..62a6e7a7365d 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "symbol.h" | 7 | #include "symbol.h" |
| 8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
| 9 | #include <linux/rbtree.h> | 9 | #include <linux/rbtree.h> |
| 10 | #include <pthread.h> | ||
| 10 | 11 | ||
| 11 | struct ins; | 12 | struct ins; |
| 12 | 13 | ||
diff --git a/tools/perf/util/dso-test-data.c b/tools/perf/util/dso-test-data.c index 541cdc72c7df..c6caedeb1d6b 100644 --- a/tools/perf/util/dso-test-data.c +++ b/tools/perf/util/dso-test-data.c | |||
| @@ -23,7 +23,7 @@ static char *test_file(int size) | |||
| 23 | int fd, i; | 23 | int fd, i; |
| 24 | unsigned char *buf; | 24 | unsigned char *buf; |
| 25 | 25 | ||
| 26 | fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC); | 26 | fd = mkstemp(templ); |
| 27 | 27 | ||
| 28 | buf = malloc(size); | 28 | buf = malloc(size); |
| 29 | if (!buf) { | 29 | if (!buf) { |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a3f562cec433..390690eb8781 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -124,6 +124,13 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); | |||
| 124 | (evsel->attr.type == PERF_TYPE_##t && \ | 124 | (evsel->attr.type == PERF_TYPE_##t && \ |
| 125 | evsel->attr.config == PERF_COUNT_##c) | 125 | evsel->attr.config == PERF_COUNT_##c) |
| 126 | 126 | ||
| 127 | static inline bool perf_evsel__match2(struct perf_evsel *e1, | ||
| 128 | struct perf_evsel *e2) | ||
| 129 | { | ||
| 130 | return (e1->attr.type == e2->attr.type) && | ||
| 131 | (e1->attr.config == e2->attr.config); | ||
| 132 | } | ||
| 133 | |||
| 127 | int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, | 134 | int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, |
| 128 | int cpu, int thread, bool scale); | 135 | int cpu, int thread, bool scale); |
| 129 | 136 | ||
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 6f2975a00358..4fa764d8f7d7 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include "exec_cmd.h" | 3 | #include "exec_cmd.h" |
| 4 | #include "levenshtein.h" | 4 | #include "levenshtein.h" |
| 5 | #include "help.h" | 5 | #include "help.h" |
| 6 | #include <termios.h> | ||
| 6 | 7 | ||
| 7 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) | 8 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) |
| 8 | { | 9 | { |
diff --git a/tools/perf/util/include/linux/rbtree.h b/tools/perf/util/include/linux/rbtree.h index 7a243a143037..2a030c5af3aa 100644 --- a/tools/perf/util/include/linux/rbtree.h +++ b/tools/perf/util/include/linux/rbtree.h | |||
| @@ -1 +1,2 @@ | |||
| 1 | #include <stdbool.h> | ||
| 1 | #include "../../../../include/linux/rbtree.h" | 2 | #include "../../../../include/linux/rbtree.h" |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 176a60902f56..aab414fbb64b 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -36,9 +36,7 @@ struct perf_session { | |||
| 36 | struct pevent *pevent; | 36 | struct pevent *pevent; |
| 37 | /* | 37 | /* |
| 38 | * FIXME: Need to split this up further, we need global | 38 | * FIXME: Need to split this up further, we need global |
| 39 | * stats + per event stats. 'perf diff' also needs | 39 | * stats + per event stats. |
| 40 | * to properly support multiple events in a single | ||
| 41 | * perf.data file. | ||
| 42 | */ | 40 | */ |
| 43 | struct hists hists; | 41 | struct hists hists; |
| 44 | int fd; | 42 | int fd; |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 0f5a0a496bc4..7a2fbd8855b7 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
| @@ -12,8 +12,6 @@ int sort__branch_mode = -1; /* -1 = means not set */ | |||
| 12 | 12 | ||
| 13 | enum sort_type sort__first_dimension; | 13 | enum sort_type sort__first_dimension; |
| 14 | 14 | ||
| 15 | char * field_sep; | ||
| 16 | |||
| 17 | LIST_HEAD(hist_entry__sort_list); | 15 | LIST_HEAD(hist_entry__sort_list); |
| 18 | 16 | ||
| 19 | static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) | 17 | static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) |
| @@ -23,11 +21,11 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) | |||
| 23 | 21 | ||
| 24 | va_start(ap, fmt); | 22 | va_start(ap, fmt); |
| 25 | n = vsnprintf(bf, size, fmt, ap); | 23 | n = vsnprintf(bf, size, fmt, ap); |
| 26 | if (field_sep && n > 0) { | 24 | if (symbol_conf.field_sep && n > 0) { |
| 27 | char *sep = bf; | 25 | char *sep = bf; |
| 28 | 26 | ||
| 29 | while (1) { | 27 | while (1) { |
| 30 | sep = strchr(sep, *field_sep); | 28 | sep = strchr(sep, *symbol_conf.field_sep); |
| 31 | if (sep == NULL) | 29 | if (sep == NULL) |
| 32 | break; | 30 | break; |
| 33 | *sep = '.'; | 31 | *sep = '.'; |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index e724b26acd51..e459c981b039 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
| @@ -32,7 +32,6 @@ extern const char default_sort_order[]; | |||
| 32 | extern int sort__need_collapse; | 32 | extern int sort__need_collapse; |
| 33 | extern int sort__has_parent; | 33 | extern int sort__has_parent; |
| 34 | extern int sort__branch_mode; | 34 | extern int sort__branch_mode; |
| 35 | extern char *field_sep; | ||
| 36 | extern struct sort_entry sort_comm; | 35 | extern struct sort_entry sort_comm; |
| 37 | extern struct sort_entry sort_dso; | 36 | extern struct sort_entry sort_dso; |
| 38 | extern struct sort_entry sort_sym; | 37 | extern struct sort_entry sort_sym; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index fc4b1e630fd9..d3b330cbc3e0 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | #include <linux/rbtree.h> | 10 | #include <linux/rbtree.h> |
| 11 | #include <stdio.h> | 11 | #include <stdio.h> |
| 12 | #include <byteswap.h> | 12 | #include <byteswap.h> |
| 13 | #if defined(__BIONIC__) | ||
| 14 | #include <libgen.h> | ||
| 15 | #endif | ||
| 13 | 16 | ||
| 14 | #ifndef NO_LIBELF_SUPPORT | 17 | #ifndef NO_LIBELF_SUPPORT |
| 15 | #include <libelf.h> | 18 | #include <libelf.h> |
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 33347ca89ee4..86ff1b15059b 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "types.h" | 5 | #include "types.h" |
| 6 | #include <stddef.h> | 6 | #include <stddef.h> |
| 7 | #include <stdbool.h> | 7 | #include <stdbool.h> |
| 8 | #include <termios.h> | ||
| 8 | 9 | ||
| 9 | struct perf_evlist; | 10 | struct perf_evlist; |
| 10 | struct perf_evsel; | 11 | struct perf_evsel; |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 1b8775c3707d..2055cf38041c 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | #include "../perf.h" | 1 | #include "../perf.h" |
| 2 | #include "util.h" | 2 | #include "util.h" |
| 3 | #include <sys/mman.h> | 3 | #include <sys/mman.h> |
| 4 | #ifndef NO_BACKTRACE | ||
| 4 | #include <execinfo.h> | 5 | #include <execinfo.h> |
| 6 | #endif | ||
| 5 | #include <stdio.h> | 7 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 8 | #include <stdlib.h> |
| 7 | 9 | ||
| @@ -163,6 +165,7 @@ size_t hex_width(u64 v) | |||
| 163 | } | 165 | } |
| 164 | 166 | ||
| 165 | /* Obtain a backtrace and print it to stdout. */ | 167 | /* Obtain a backtrace and print it to stdout. */ |
| 168 | #ifndef NO_BACKTRACE | ||
| 166 | void dump_stack(void) | 169 | void dump_stack(void) |
| 167 | { | 170 | { |
| 168 | void *array[16]; | 171 | void *array[16]; |
| @@ -177,3 +180,6 @@ void dump_stack(void) | |||
| 177 | 180 | ||
| 178 | free(strings); | 181 | free(strings); |
| 179 | } | 182 | } |
| 183 | #else | ||
| 184 | void dump_stack(void) {} | ||
| 185 | #endif | ||
