diff options
Diffstat (limited to 'tools/perf')
82 files changed, 908 insertions, 764 deletions
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 97a2145e4cc6..3638b0bd20dc 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -489,6 +489,7 @@ ifndef NO_SLANG | |||
489 | LIB_OBJS += $(OUTPUT)ui/browsers/hists.o | 489 | LIB_OBJS += $(OUTPUT)ui/browsers/hists.o |
490 | LIB_OBJS += $(OUTPUT)ui/browsers/map.o | 490 | LIB_OBJS += $(OUTPUT)ui/browsers/map.o |
491 | LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o | 491 | LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o |
492 | LIB_OBJS += $(OUTPUT)ui/browsers/header.o | ||
492 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o | 493 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o |
493 | LIB_OBJS += $(OUTPUT)ui/tui/util.o | 494 | LIB_OBJS += $(OUTPUT)ui/tui/util.o |
494 | LIB_OBJS += $(OUTPUT)ui/tui/helpline.o | 495 | LIB_OBJS += $(OUTPUT)ui/tui/helpline.o |
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index aacef07ebf31..42faf369211c 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c | |||
@@ -154,8 +154,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, | |||
154 | } | 154 | } |
155 | if (lookup_path(buf)) | 155 | if (lookup_path(buf)) |
156 | goto out; | 156 | goto out; |
157 | free(buf); | 157 | zfree(&buf); |
158 | buf = NULL; | ||
159 | } | 158 | } |
160 | 159 | ||
161 | if (!strcmp(arch, "arm")) | 160 | if (!strcmp(arch, "arm")) |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6fd52c8fa682..ab65057a0317 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -69,15 +69,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, | |||
69 | if (he == NULL) | 69 | if (he == NULL) |
70 | return -ENOMEM; | 70 | return -ENOMEM; |
71 | 71 | ||
72 | ret = 0; | 72 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
73 | if (he->ms.sym != NULL) { | ||
74 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
75 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
76 | return -ENOMEM; | ||
77 | |||
78 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
79 | } | ||
80 | |||
81 | evsel->hists.stats.total_period += sample->period; | 73 | evsel->hists.stats.total_period += sample->period; |
82 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 74 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
83 | return ret; | 75 | return ret; |
@@ -188,8 +180,7 @@ find_next: | |||
188 | * symbol, free he->ms.sym->src to signal we already | 180 | * symbol, free he->ms.sym->src to signal we already |
189 | * processed this symbol. | 181 | * processed this symbol. |
190 | */ | 182 | */ |
191 | free(notes->src); | 183 | zfree(¬es->src); |
192 | notes->src = NULL; | ||
193 | } | 184 | } |
194 | } | 185 | } |
195 | } | 186 | } |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 2a85cc9a2d09..e6a0844bc2f0 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -654,7 +654,7 @@ static void data__free(struct data__file *d) | |||
654 | for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { | 654 | for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { |
655 | struct diff_hpp_fmt *fmt = &d->fmt[col]; | 655 | struct diff_hpp_fmt *fmt = &d->fmt[col]; |
656 | 656 | ||
657 | free(fmt->header); | 657 | zfree(&fmt->header); |
658 | } | 658 | } |
659 | } | 659 | } |
660 | 660 | ||
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 6a2508589460..c9f6d74e1fd7 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -22,14 +22,13 @@ | |||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | 23 | ||
24 | struct perf_inject { | 24 | struct perf_inject { |
25 | struct perf_tool tool; | 25 | struct perf_tool tool; |
26 | bool build_ids; | 26 | bool build_ids; |
27 | bool sched_stat; | 27 | bool sched_stat; |
28 | const char *input_name; | 28 | const char *input_name; |
29 | int pipe_output, | 29 | struct perf_data_file output; |
30 | output; | 30 | u64 bytes_written; |
31 | u64 bytes_written; | 31 | struct list_head samples; |
32 | struct list_head samples; | ||
33 | }; | 32 | }; |
34 | 33 | ||
35 | struct event_entry { | 34 | struct event_entry { |
@@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool, | |||
42 | union perf_event *event) | 41 | union perf_event *event) |
43 | { | 42 | { |
44 | struct perf_inject *inject = container_of(tool, struct perf_inject, tool); | 43 | struct perf_inject *inject = container_of(tool, struct perf_inject, tool); |
45 | uint32_t size; | 44 | ssize_t size; |
46 | void *buf = event; | ||
47 | 45 | ||
48 | size = event->header.size; | 46 | size = perf_data_file__write(&inject->output, event, |
49 | 47 | event->header.size); | |
50 | while (size) { | 48 | if (size < 0) |
51 | int ret = write(inject->output, buf, size); | 49 | return -errno; |
52 | if (ret < 0) | ||
53 | return -errno; | ||
54 | |||
55 | size -= ret; | ||
56 | buf += ret; | ||
57 | inject->bytes_written += ret; | ||
58 | } | ||
59 | 50 | ||
51 | inject->bytes_written += size; | ||
60 | return 0; | 52 | return 0; |
61 | } | 53 | } |
62 | 54 | ||
@@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool, | |||
80 | if (ret) | 72 | if (ret) |
81 | return ret; | 73 | return ret; |
82 | 74 | ||
83 | if (!inject->pipe_output) | 75 | if (&inject->output.is_pipe) |
84 | return 0; | 76 | return 0; |
85 | 77 | ||
86 | return perf_event__repipe_synth(tool, event); | 78 | return perf_event__repipe_synth(tool, event); |
@@ -355,6 +347,7 @@ static int __cmd_inject(struct perf_inject *inject) | |||
355 | .path = inject->input_name, | 347 | .path = inject->input_name, |
356 | .mode = PERF_DATA_MODE_READ, | 348 | .mode = PERF_DATA_MODE_READ, |
357 | }; | 349 | }; |
350 | struct perf_data_file *file_out = &inject->output; | ||
358 | 351 | ||
359 | signal(SIGINT, sig_handler); | 352 | signal(SIGINT, sig_handler); |
360 | 353 | ||
@@ -391,14 +384,14 @@ static int __cmd_inject(struct perf_inject *inject) | |||
391 | } | 384 | } |
392 | } | 385 | } |
393 | 386 | ||
394 | if (!inject->pipe_output) | 387 | if (!file_out->is_pipe) |
395 | lseek(inject->output, session->header.data_offset, SEEK_SET); | 388 | lseek(file_out->fd, session->header.data_offset, SEEK_SET); |
396 | 389 | ||
397 | ret = perf_session__process_events(session, &inject->tool); | 390 | ret = perf_session__process_events(session, &inject->tool); |
398 | 391 | ||
399 | if (!inject->pipe_output) { | 392 | if (!file_out->is_pipe) { |
400 | session->header.data_size = inject->bytes_written; | 393 | session->header.data_size = inject->bytes_written; |
401 | perf_session__write_header(session, session->evlist, inject->output, true); | 394 | perf_session__write_header(session, session->evlist, file_out->fd, true); |
402 | } | 395 | } |
403 | 396 | ||
404 | perf_session__delete(session); | 397 | perf_session__delete(session); |
@@ -427,14 +420,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | |||
427 | }, | 420 | }, |
428 | .input_name = "-", | 421 | .input_name = "-", |
429 | .samples = LIST_HEAD_INIT(inject.samples), | 422 | .samples = LIST_HEAD_INIT(inject.samples), |
423 | .output = { | ||
424 | .path = "-", | ||
425 | .mode = PERF_DATA_MODE_WRITE, | ||
426 | }, | ||
430 | }; | 427 | }; |
431 | const char *output_name = "-"; | ||
432 | const struct option options[] = { | 428 | const struct option options[] = { |
433 | OPT_BOOLEAN('b', "build-ids", &inject.build_ids, | 429 | OPT_BOOLEAN('b', "build-ids", &inject.build_ids, |
434 | "Inject build-ids into the output stream"), | 430 | "Inject build-ids into the output stream"), |
435 | OPT_STRING('i', "input", &inject.input_name, "file", | 431 | OPT_STRING('i', "input", &inject.input_name, "file", |
436 | "input file name"), | 432 | "input file name"), |
437 | OPT_STRING('o', "output", &output_name, "file", | 433 | OPT_STRING('o', "output", &inject.output.path, "file", |
438 | "output file name"), | 434 | "output file name"), |
439 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, | 435 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, |
440 | "Merge sched-stat and sched-switch for getting events " | 436 | "Merge sched-stat and sched-switch for getting events " |
@@ -456,16 +452,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | |||
456 | if (argc) | 452 | if (argc) |
457 | usage_with_options(inject_usage, options); | 453 | usage_with_options(inject_usage, options); |
458 | 454 | ||
459 | if (!strcmp(output_name, "-")) { | 455 | if (perf_data_file__open(&inject.output)) { |
460 | inject.pipe_output = 1; | 456 | perror("failed to create output file"); |
461 | inject.output = STDOUT_FILENO; | 457 | return -1; |
462 | } else { | ||
463 | inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC, | ||
464 | S_IRUSR | S_IWUSR); | ||
465 | if (inject.output < 0) { | ||
466 | perror("failed to create output file"); | ||
467 | return -1; | ||
468 | } | ||
469 | } | 458 | } |
470 | 459 | ||
471 | if (symbol__init() < 0) | 460 | if (symbol__init() < 0) |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 154b397a5d27..a6ec1052c291 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -89,7 +89,7 @@ struct exit_reasons_table { | |||
89 | 89 | ||
90 | struct perf_kvm_stat { | 90 | struct perf_kvm_stat { |
91 | struct perf_tool tool; | 91 | struct perf_tool tool; |
92 | struct perf_record_opts opts; | 92 | struct record_opts opts; |
93 | struct perf_evlist *evlist; | 93 | struct perf_evlist *evlist; |
94 | struct perf_session *session; | 94 | struct perf_session *session; |
95 | 95 | ||
@@ -1158,9 +1158,7 @@ out: | |||
1158 | if (kvm->timerfd >= 0) | 1158 | if (kvm->timerfd >= 0) |
1159 | close(kvm->timerfd); | 1159 | close(kvm->timerfd); |
1160 | 1160 | ||
1161 | if (pollfds) | 1161 | free(pollfds); |
1162 | free(pollfds); | ||
1163 | |||
1164 | return err; | 1162 | return err; |
1165 | } | 1163 | } |
1166 | 1164 | ||
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 31c00f186da1..2e3ade69a58e 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
@@ -62,7 +62,6 @@ static int | |||
62 | dump_raw_samples(struct perf_tool *tool, | 62 | dump_raw_samples(struct perf_tool *tool, |
63 | union perf_event *event, | 63 | union perf_event *event, |
64 | struct perf_sample *sample, | 64 | struct perf_sample *sample, |
65 | struct perf_evsel *evsel __maybe_unused, | ||
66 | struct machine *machine) | 65 | struct machine *machine) |
67 | { | 66 | { |
68 | struct perf_mem *mem = container_of(tool, struct perf_mem, tool); | 67 | struct perf_mem *mem = container_of(tool, struct perf_mem, tool); |
@@ -112,10 +111,10 @@ dump_raw_samples(struct perf_tool *tool, | |||
112 | static int process_sample_event(struct perf_tool *tool, | 111 | static int process_sample_event(struct perf_tool *tool, |
113 | union perf_event *event, | 112 | union perf_event *event, |
114 | struct perf_sample *sample, | 113 | struct perf_sample *sample, |
115 | struct perf_evsel *evsel, | 114 | struct perf_evsel *evsel __maybe_unused, |
116 | struct machine *machine) | 115 | struct machine *machine) |
117 | { | 116 | { |
118 | return dump_raw_samples(tool, event, sample, evsel, machine); | 117 | return dump_raw_samples(tool, event, sample, machine); |
119 | } | 118 | } |
120 | 119 | ||
121 | static int report_raw_events(struct perf_mem *mem) | 120 | static int report_raw_events(struct perf_mem *mem) |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c98ccb570509..43ff33d0007b 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -169,6 +169,7 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
169 | int unset __maybe_unused) | 169 | int unset __maybe_unused) |
170 | { | 170 | { |
171 | int ret = -ENOENT; | 171 | int ret = -ENOENT; |
172 | char *tmp; | ||
172 | 173 | ||
173 | if (str && !params.target) { | 174 | if (str && !params.target) { |
174 | if (!strcmp(opt->long_name, "exec")) | 175 | if (!strcmp(opt->long_name, "exec")) |
@@ -180,7 +181,19 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
180 | else | 181 | else |
181 | return ret; | 182 | return ret; |
182 | 183 | ||
183 | params.target = str; | 184 | /* Expand given path to absolute path, except for modulename */ |
185 | if (params.uprobes || strchr(str, '/')) { | ||
186 | tmp = realpath(str, NULL); | ||
187 | if (!tmp) { | ||
188 | pr_warning("Failed to get the absolute path of %s: %m\n", str); | ||
189 | return ret; | ||
190 | } | ||
191 | } else { | ||
192 | tmp = strdup(str); | ||
193 | if (!tmp) | ||
194 | return -ENOMEM; | ||
195 | } | ||
196 | params.target = tmp; | ||
184 | ret = 0; | 197 | ret = 0; |
185 | } | 198 | } |
186 | 199 | ||
@@ -411,7 +424,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
411 | } | 424 | } |
412 | 425 | ||
413 | #ifdef HAVE_DWARF_SUPPORT | 426 | #ifdef HAVE_DWARF_SUPPORT |
414 | if (params.show_lines && !params.uprobes) { | 427 | if (params.show_lines) { |
415 | if (params.mod_events) { | 428 | if (params.mod_events) { |
416 | pr_err(" Error: Don't use --line with" | 429 | pr_err(" Error: Don't use --line with" |
417 | " --add/--del.\n"); | 430 | " --add/--del.\n"); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index c1c1200d2f0a..6ec0cbc2a5d5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -62,9 +62,9 @@ static void __handle_on_exit_funcs(void) | |||
62 | } | 62 | } |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | struct perf_record { | 65 | struct record { |
66 | struct perf_tool tool; | 66 | struct perf_tool tool; |
67 | struct perf_record_opts opts; | 67 | struct record_opts opts; |
68 | u64 bytes_written; | 68 | u64 bytes_written; |
69 | struct perf_data_file file; | 69 | struct perf_data_file file; |
70 | struct perf_evlist *evlist; | 70 | struct perf_evlist *evlist; |
@@ -76,24 +76,14 @@ struct perf_record { | |||
76 | long samples; | 76 | long samples; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int perf_record__write(struct perf_record *rec, void *buf, size_t size) | 79 | static int record__write(struct record *rec, void *bf, size_t size) |
80 | { | 80 | { |
81 | struct perf_data_file *file = &rec->file; | 81 | if (perf_data_file__write(rec->session->file, bf, size) < 0) { |
82 | 82 | pr_err("failed to write perf data, error: %m\n"); | |
83 | while (size) { | 83 | return -1; |
84 | ssize_t ret = write(file->fd, buf, size); | ||
85 | |||
86 | if (ret < 0) { | ||
87 | pr_err("failed to write perf data, error: %m\n"); | ||
88 | return -1; | ||
89 | } | ||
90 | |||
91 | size -= ret; | ||
92 | buf += ret; | ||
93 | |||
94 | rec->bytes_written += ret; | ||
95 | } | 84 | } |
96 | 85 | ||
86 | rec->bytes_written += size; | ||
97 | return 0; | 87 | return 0; |
98 | } | 88 | } |
99 | 89 | ||
@@ -102,12 +92,11 @@ static int process_synthesized_event(struct perf_tool *tool, | |||
102 | struct perf_sample *sample __maybe_unused, | 92 | struct perf_sample *sample __maybe_unused, |
103 | struct machine *machine __maybe_unused) | 93 | struct machine *machine __maybe_unused) |
104 | { | 94 | { |
105 | struct perf_record *rec = container_of(tool, struct perf_record, tool); | 95 | struct record *rec = container_of(tool, struct record, tool); |
106 | return perf_record__write(rec, event, event->header.size); | 96 | return record__write(rec, event, event->header.size); |
107 | } | 97 | } |
108 | 98 | ||
109 | static int perf_record__mmap_read(struct perf_record *rec, | 99 | static int record__mmap_read(struct record *rec, struct perf_mmap *md) |
110 | struct perf_mmap *md) | ||
111 | { | 100 | { |
112 | unsigned int head = perf_mmap__read_head(md); | 101 | unsigned int head = perf_mmap__read_head(md); |
113 | unsigned int old = md->prev; | 102 | unsigned int old = md->prev; |
@@ -128,7 +117,7 @@ static int perf_record__mmap_read(struct perf_record *rec, | |||
128 | size = md->mask + 1 - (old & md->mask); | 117 | size = md->mask + 1 - (old & md->mask); |
129 | old += size; | 118 | old += size; |
130 | 119 | ||
131 | if (perf_record__write(rec, buf, size) < 0) { | 120 | if (record__write(rec, buf, size) < 0) { |
132 | rc = -1; | 121 | rc = -1; |
133 | goto out; | 122 | goto out; |
134 | } | 123 | } |
@@ -138,7 +127,7 @@ static int perf_record__mmap_read(struct perf_record *rec, | |||
138 | size = head - old; | 127 | size = head - old; |
139 | old += size; | 128 | old += size; |
140 | 129 | ||
141 | if (perf_record__write(rec, buf, size) < 0) { | 130 | if (record__write(rec, buf, size) < 0) { |
142 | rc = -1; | 131 | rc = -1; |
143 | goto out; | 132 | goto out; |
144 | } | 133 | } |
@@ -163,9 +152,9 @@ static void sig_handler(int sig) | |||
163 | signr = sig; | 152 | signr = sig; |
164 | } | 153 | } |
165 | 154 | ||
166 | static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) | 155 | static void record__sig_exit(int exit_status __maybe_unused, void *arg) |
167 | { | 156 | { |
168 | struct perf_record *rec = arg; | 157 | struct record *rec = arg; |
169 | int status; | 158 | int status; |
170 | 159 | ||
171 | if (rec->evlist->workload.pid > 0) { | 160 | if (rec->evlist->workload.pid > 0) { |
@@ -183,13 +172,13 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) | |||
183 | signal(signr, SIG_DFL); | 172 | signal(signr, SIG_DFL); |
184 | } | 173 | } |
185 | 174 | ||
186 | static int perf_record__open(struct perf_record *rec) | 175 | static int record__open(struct record *rec) |
187 | { | 176 | { |
188 | char msg[512]; | 177 | char msg[512]; |
189 | struct perf_evsel *pos; | 178 | struct perf_evsel *pos; |
190 | struct perf_evlist *evlist = rec->evlist; | 179 | struct perf_evlist *evlist = rec->evlist; |
191 | struct perf_session *session = rec->session; | 180 | struct perf_session *session = rec->session; |
192 | struct perf_record_opts *opts = &rec->opts; | 181 | struct record_opts *opts = &rec->opts; |
193 | int rc = 0; | 182 | int rc = 0; |
194 | 183 | ||
195 | perf_evlist__config(evlist, opts); | 184 | perf_evlist__config(evlist, opts); |
@@ -239,7 +228,7 @@ out: | |||
239 | return rc; | 228 | return rc; |
240 | } | 229 | } |
241 | 230 | ||
242 | static int process_buildids(struct perf_record *rec) | 231 | static int process_buildids(struct record *rec) |
243 | { | 232 | { |
244 | struct perf_data_file *file = &rec->file; | 233 | struct perf_data_file *file = &rec->file; |
245 | struct perf_session *session = rec->session; | 234 | struct perf_session *session = rec->session; |
@@ -254,9 +243,9 @@ static int process_buildids(struct perf_record *rec) | |||
254 | size, &build_id__mark_dso_hit_ops); | 243 | size, &build_id__mark_dso_hit_ops); |
255 | } | 244 | } |
256 | 245 | ||
257 | static void perf_record__exit(int status, void *arg) | 246 | static void record__exit(int status, void *arg) |
258 | { | 247 | { |
259 | struct perf_record *rec = arg; | 248 | struct record *rec = arg; |
260 | struct perf_data_file *file = &rec->file; | 249 | struct perf_data_file *file = &rec->file; |
261 | 250 | ||
262 | if (status != 0) | 251 | if (status != 0) |
@@ -312,14 +301,14 @@ static struct perf_event_header finished_round_event = { | |||
312 | .type = PERF_RECORD_FINISHED_ROUND, | 301 | .type = PERF_RECORD_FINISHED_ROUND, |
313 | }; | 302 | }; |
314 | 303 | ||
315 | static int perf_record__mmap_read_all(struct perf_record *rec) | 304 | static int record__mmap_read_all(struct record *rec) |
316 | { | 305 | { |
317 | int i; | 306 | int i; |
318 | int rc = 0; | 307 | int rc = 0; |
319 | 308 | ||
320 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { | 309 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { |
321 | if (rec->evlist->mmap[i].base) { | 310 | if (rec->evlist->mmap[i].base) { |
322 | if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { | 311 | if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { |
323 | rc = -1; | 312 | rc = -1; |
324 | goto out; | 313 | goto out; |
325 | } | 314 | } |
@@ -327,14 +316,13 @@ static int perf_record__mmap_read_all(struct perf_record *rec) | |||
327 | } | 316 | } |
328 | 317 | ||
329 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) | 318 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) |
330 | rc = perf_record__write(rec, &finished_round_event, | 319 | rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); |
331 | sizeof(finished_round_event)); | ||
332 | 320 | ||
333 | out: | 321 | out: |
334 | return rc; | 322 | return rc; |
335 | } | 323 | } |
336 | 324 | ||
337 | static void perf_record__init_features(struct perf_record *rec) | 325 | static void record__init_features(struct record *rec) |
338 | { | 326 | { |
339 | struct perf_evlist *evsel_list = rec->evlist; | 327 | struct perf_evlist *evsel_list = rec->evlist; |
340 | struct perf_session *session = rec->session; | 328 | struct perf_session *session = rec->session; |
@@ -353,14 +341,14 @@ static void perf_record__init_features(struct perf_record *rec) | |||
353 | perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); | 341 | perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); |
354 | } | 342 | } |
355 | 343 | ||
356 | static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | 344 | static int __cmd_record(struct record *rec, int argc, const char **argv) |
357 | { | 345 | { |
358 | int err; | 346 | int err; |
359 | unsigned long waking = 0; | 347 | unsigned long waking = 0; |
360 | const bool forks = argc > 0; | 348 | const bool forks = argc > 0; |
361 | struct machine *machine; | 349 | struct machine *machine; |
362 | struct perf_tool *tool = &rec->tool; | 350 | struct perf_tool *tool = &rec->tool; |
363 | struct perf_record_opts *opts = &rec->opts; | 351 | struct record_opts *opts = &rec->opts; |
364 | struct perf_evlist *evsel_list = rec->evlist; | 352 | struct perf_evlist *evsel_list = rec->evlist; |
365 | struct perf_data_file *file = &rec->file; | 353 | struct perf_data_file *file = &rec->file; |
366 | struct perf_session *session; | 354 | struct perf_session *session; |
@@ -368,7 +356,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
368 | 356 | ||
369 | rec->progname = argv[0]; | 357 | rec->progname = argv[0]; |
370 | 358 | ||
371 | on_exit(perf_record__sig_exit, rec); | 359 | on_exit(record__sig_exit, rec); |
372 | signal(SIGCHLD, sig_handler); | 360 | signal(SIGCHLD, sig_handler); |
373 | signal(SIGINT, sig_handler); | 361 | signal(SIGINT, sig_handler); |
374 | signal(SIGUSR1, sig_handler); | 362 | signal(SIGUSR1, sig_handler); |
@@ -382,7 +370,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
382 | 370 | ||
383 | rec->session = session; | 371 | rec->session = session; |
384 | 372 | ||
385 | perf_record__init_features(rec); | 373 | record__init_features(rec); |
386 | 374 | ||
387 | if (forks) { | 375 | if (forks) { |
388 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, | 376 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, |
@@ -394,7 +382,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
394 | } | 382 | } |
395 | } | 383 | } |
396 | 384 | ||
397 | if (perf_record__open(rec) != 0) { | 385 | if (record__open(rec) != 0) { |
398 | err = -1; | 386 | err = -1; |
399 | goto out_delete_session; | 387 | goto out_delete_session; |
400 | } | 388 | } |
@@ -403,9 +391,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
403 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); | 391 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); |
404 | 392 | ||
405 | /* | 393 | /* |
406 | * perf_session__delete(session) will be called at perf_record__exit() | 394 | * perf_session__delete(session) will be called at record__exit() |
407 | */ | 395 | */ |
408 | on_exit(perf_record__exit, rec); | 396 | on_exit(record__exit, rec); |
409 | 397 | ||
410 | if (file->is_pipe) { | 398 | if (file->is_pipe) { |
411 | err = perf_header__write_pipe(file->fd); | 399 | err = perf_header__write_pipe(file->fd); |
@@ -510,7 +498,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
510 | for (;;) { | 498 | for (;;) { |
511 | int hits = rec->samples; | 499 | int hits = rec->samples; |
512 | 500 | ||
513 | if (perf_record__mmap_read_all(rec) < 0) { | 501 | if (record__mmap_read_all(rec) < 0) { |
514 | err = -1; | 502 | err = -1; |
515 | goto out_delete_session; | 503 | goto out_delete_session; |
516 | } | 504 | } |
@@ -669,7 +657,7 @@ static int get_stack_size(char *str, unsigned long *_size) | |||
669 | } | 657 | } |
670 | #endif /* HAVE_LIBUNWIND_SUPPORT */ | 658 | #endif /* HAVE_LIBUNWIND_SUPPORT */ |
671 | 659 | ||
672 | int record_parse_callchain(const char *arg, struct perf_record_opts *opts) | 660 | int record_parse_callchain(const char *arg, struct record_opts *opts) |
673 | { | 661 | { |
674 | char *tok, *name, *saveptr = NULL; | 662 | char *tok, *name, *saveptr = NULL; |
675 | char *buf; | 663 | char *buf; |
@@ -725,7 +713,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts) | |||
725 | return ret; | 713 | return ret; |
726 | } | 714 | } |
727 | 715 | ||
728 | static void callchain_debug(struct perf_record_opts *opts) | 716 | static void callchain_debug(struct record_opts *opts) |
729 | { | 717 | { |
730 | pr_debug("callchain: type %d\n", opts->call_graph); | 718 | pr_debug("callchain: type %d\n", opts->call_graph); |
731 | 719 | ||
@@ -738,7 +726,7 @@ int record_parse_callchain_opt(const struct option *opt, | |||
738 | const char *arg, | 726 | const char *arg, |
739 | int unset) | 727 | int unset) |
740 | { | 728 | { |
741 | struct perf_record_opts *opts = opt->value; | 729 | struct record_opts *opts = opt->value; |
742 | int ret; | 730 | int ret; |
743 | 731 | ||
744 | /* --no-call-graph */ | 732 | /* --no-call-graph */ |
@@ -759,7 +747,7 @@ int record_callchain_opt(const struct option *opt, | |||
759 | const char *arg __maybe_unused, | 747 | const char *arg __maybe_unused, |
760 | int unset __maybe_unused) | 748 | int unset __maybe_unused) |
761 | { | 749 | { |
762 | struct perf_record_opts *opts = opt->value; | 750 | struct record_opts *opts = opt->value; |
763 | 751 | ||
764 | if (opts->call_graph == CALLCHAIN_NONE) | 752 | if (opts->call_graph == CALLCHAIN_NONE) |
765 | opts->call_graph = CALLCHAIN_FP; | 753 | opts->call_graph = CALLCHAIN_FP; |
@@ -775,8 +763,8 @@ static const char * const record_usage[] = { | |||
775 | }; | 763 | }; |
776 | 764 | ||
777 | /* | 765 | /* |
778 | * XXX Ideally would be local to cmd_record() and passed to a perf_record__new | 766 | * XXX Ideally would be local to cmd_record() and passed to a record__new |
779 | * because we need to have access to it in perf_record__exit, that is called | 767 | * because we need to have access to it in record__exit, that is called |
780 | * after cmd_record() exits, but since record_options need to be accessible to | 768 | * after cmd_record() exits, but since record_options need to be accessible to |
781 | * builtin-script, leave it here. | 769 | * builtin-script, leave it here. |
782 | * | 770 | * |
@@ -784,7 +772,7 @@ static const char * const record_usage[] = { | |||
784 | * | 772 | * |
785 | * Just say no to tons of global variables, sigh. | 773 | * Just say no to tons of global variables, sigh. |
786 | */ | 774 | */ |
787 | static struct perf_record record = { | 775 | static struct record record = { |
788 | .opts = { | 776 | .opts = { |
789 | .mmap_pages = UINT_MAX, | 777 | .mmap_pages = UINT_MAX, |
790 | .user_freq = UINT_MAX, | 778 | .user_freq = UINT_MAX, |
@@ -808,7 +796,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp"; | |||
808 | /* | 796 | /* |
809 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing | 797 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing |
810 | * with it and switch to use the library functions in perf_evlist that came | 798 | * with it and switch to use the library functions in perf_evlist that came |
811 | * from builtin-record.c, i.e. use perf_record_opts, | 799 | * from builtin-record.c, i.e. use record_opts, |
812 | * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', | 800 | * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', |
813 | * using pipes, etc. | 801 | * using pipes, etc. |
814 | */ | 802 | */ |
@@ -891,7 +879,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
891 | { | 879 | { |
892 | int err = -ENOMEM; | 880 | int err = -ENOMEM; |
893 | struct perf_evlist *evsel_list; | 881 | struct perf_evlist *evsel_list; |
894 | struct perf_record *rec = &record; | 882 | struct record *rec = &record; |
895 | char errbuf[BUFSIZ]; | 883 | char errbuf[BUFSIZ]; |
896 | 884 | ||
897 | evsel_list = perf_evlist__new(); | 885 | evsel_list = perf_evlist__new(); |
@@ -956,7 +944,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
956 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) | 944 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) |
957 | usage_with_options(record_usage, record_options); | 945 | usage_with_options(record_usage, record_options); |
958 | 946 | ||
959 | if (perf_record_opts__config(&rec->opts)) { | 947 | if (record_opts__config(&rec->opts)) { |
960 | err = -EINVAL; | 948 | err = -EINVAL; |
961 | goto out_free_fd; | 949 | goto out_free_fd; |
962 | } | 950 | } |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3a14dbed387c..bf8dd2e893e4 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <dlfcn.h> | 39 | #include <dlfcn.h> |
40 | #include <linux/bitmap.h> | 40 | #include <linux/bitmap.h> |
41 | 41 | ||
42 | struct perf_report { | 42 | struct report { |
43 | struct perf_tool tool; | 43 | struct perf_tool tool; |
44 | struct perf_session *session; | 44 | struct perf_session *session; |
45 | bool force, use_tui, use_gtk, use_stdio; | 45 | bool force, use_tui, use_gtk, use_stdio; |
@@ -60,14 +60,14 @@ struct perf_report { | |||
60 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); | 60 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static int perf_report_config(const char *var, const char *value, void *cb) | 63 | static int report__config(const char *var, const char *value, void *cb) |
64 | { | 64 | { |
65 | if (!strcmp(var, "report.group")) { | 65 | if (!strcmp(var, "report.group")) { |
66 | symbol_conf.event_group = perf_config_bool(var, value); | 66 | symbol_conf.event_group = perf_config_bool(var, value); |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | if (!strcmp(var, "report.percent-limit")) { | 69 | if (!strcmp(var, "report.percent-limit")) { |
70 | struct perf_report *rep = cb; | 70 | struct report *rep = cb; |
71 | rep->min_percent = strtof(value, NULL); | 71 | rep->min_percent = strtof(value, NULL); |
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
@@ -75,31 +75,40 @@ static int perf_report_config(const char *var, const char *value, void *cb) | |||
75 | return perf_default_config(var, value, cb); | 75 | return perf_default_config(var, value, cb); |
76 | } | 76 | } |
77 | 77 | ||
78 | static int perf_report__add_mem_hist_entry(struct perf_tool *tool, | 78 | static int report__resolve_callchain(struct report *rep, struct symbol **parent, |
79 | struct addr_location *al, | 79 | struct perf_evsel *evsel, struct addr_location *al, |
80 | struct perf_sample *sample, | 80 | struct perf_sample *sample) |
81 | struct perf_evsel *evsel, | ||
82 | struct machine *machine, | ||
83 | union perf_event *event) | ||
84 | { | 81 | { |
85 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 82 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { |
83 | return machine__resolve_callchain(al->machine, evsel, al->thread, sample, | ||
84 | parent, al, rep->max_stack); | ||
85 | } | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample) | ||
90 | { | ||
91 | if (!symbol_conf.use_callchain) | ||
92 | return 0; | ||
93 | return callchain_append(he->callchain, &callchain_cursor, sample->period); | ||
94 | } | ||
95 | |||
96 | static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al, | ||
97 | struct perf_sample *sample, struct perf_evsel *evsel, | ||
98 | union perf_event *event) | ||
99 | { | ||
100 | struct report *rep = container_of(tool, struct report, tool); | ||
86 | struct symbol *parent = NULL; | 101 | struct symbol *parent = NULL; |
87 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 102 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
88 | int err = 0; | ||
89 | struct hist_entry *he; | 103 | struct hist_entry *he; |
90 | struct mem_info *mi, *mx; | 104 | struct mem_info *mi, *mx; |
91 | uint64_t cost; | 105 | uint64_t cost; |
106 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
92 | 107 | ||
93 | if ((sort__has_parent || symbol_conf.use_callchain) && | 108 | if (err) |
94 | sample->callchain) { | 109 | return err; |
95 | err = machine__resolve_callchain(machine, evsel, al->thread, | ||
96 | sample, &parent, al, | ||
97 | rep->max_stack); | ||
98 | if (err) | ||
99 | return err; | ||
100 | } | ||
101 | 110 | ||
102 | mi = machine__resolve_mem(machine, al->thread, sample, cpumode); | 111 | mi = machine__resolve_mem(al->machine, al->thread, sample, cpumode); |
103 | if (!mi) | 112 | if (!mi) |
104 | return -ENOMEM; | 113 | return -ENOMEM; |
105 | 114 | ||
@@ -122,77 +131,36 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool, | |||
122 | if (!he) | 131 | if (!he) |
123 | return -ENOMEM; | 132 | return -ENOMEM; |
124 | 133 | ||
125 | /* | 134 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
126 | * In the TUI browser, we are doing integrated annotation, | 135 | if (err) |
127 | * so we don't allocate the extra space needed because the stdio | 136 | goto out; |
128 | * code will not use it. | ||
129 | */ | ||
130 | if (sort__has_sym && he->ms.sym && use_browser > 0) { | ||
131 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
132 | |||
133 | assert(evsel != NULL); | ||
134 | |||
135 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
136 | goto out; | ||
137 | |||
138 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
139 | if (err) | ||
140 | goto out; | ||
141 | } | ||
142 | |||
143 | if (sort__has_sym && he->mem_info->daddr.sym && use_browser > 0) { | ||
144 | struct annotation *notes; | ||
145 | |||
146 | mx = he->mem_info; | ||
147 | 137 | ||
148 | notes = symbol__annotation(mx->daddr.sym); | 138 | mx = he->mem_info; |
149 | if (notes->src == NULL && symbol__alloc_hist(mx->daddr.sym) < 0) | 139 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); |
150 | goto out; | 140 | if (err) |
151 | 141 | goto out; | |
152 | err = symbol__inc_addr_samples(mx->daddr.sym, | ||
153 | mx->daddr.map, | ||
154 | evsel->idx, | ||
155 | mx->daddr.al_addr); | ||
156 | if (err) | ||
157 | goto out; | ||
158 | } | ||
159 | 142 | ||
160 | evsel->hists.stats.total_period += cost; | 143 | evsel->hists.stats.total_period += cost; |
161 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 144 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
162 | err = 0; | 145 | err = hist_entry__append_callchain(he, sample); |
163 | |||
164 | if (symbol_conf.use_callchain) { | ||
165 | err = callchain_append(he->callchain, | ||
166 | &callchain_cursor, | ||
167 | sample->period); | ||
168 | } | ||
169 | out: | 146 | out: |
170 | return err; | 147 | return err; |
171 | } | 148 | } |
172 | 149 | ||
173 | static int perf_report__add_branch_hist_entry(struct perf_tool *tool, | 150 | static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_location *al, |
174 | struct addr_location *al, | 151 | struct perf_sample *sample, struct perf_evsel *evsel) |
175 | struct perf_sample *sample, | ||
176 | struct perf_evsel *evsel, | ||
177 | struct machine *machine) | ||
178 | { | 152 | { |
179 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 153 | struct report *rep = container_of(tool, struct report, tool); |
180 | struct symbol *parent = NULL; | 154 | struct symbol *parent = NULL; |
181 | int err = 0; | ||
182 | unsigned i; | 155 | unsigned i; |
183 | struct hist_entry *he; | 156 | struct hist_entry *he; |
184 | struct branch_info *bi, *bx; | 157 | struct branch_info *bi, *bx; |
158 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
185 | 159 | ||
186 | if ((sort__has_parent || symbol_conf.use_callchain) | 160 | if (err) |
187 | && sample->callchain) { | 161 | return err; |
188 | err = machine__resolve_callchain(machine, evsel, al->thread, | ||
189 | sample, &parent, al, | ||
190 | rep->max_stack); | ||
191 | if (err) | ||
192 | return err; | ||
193 | } | ||
194 | 162 | ||
195 | bi = machine__resolve_bstack(machine, al->thread, | 163 | bi = machine__resolve_bstack(al->machine, al->thread, |
196 | sample->branch_stack); | 164 | sample->branch_stack); |
197 | if (!bi) | 165 | if (!bi) |
198 | return -ENOMEM; | 166 | return -ENOMEM; |
@@ -214,35 +182,15 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, | |||
214 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, | 182 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, |
215 | 1, 1, 0); | 183 | 1, 1, 0); |
216 | if (he) { | 184 | if (he) { |
217 | struct annotation *notes; | ||
218 | bx = he->branch_info; | 185 | bx = he->branch_info; |
219 | if (bx->from.sym && use_browser == 1 && sort__has_sym) { | 186 | err = addr_map_symbol__inc_samples(&bx->from, evsel->idx); |
220 | notes = symbol__annotation(bx->from.sym); | 187 | if (err) |
221 | if (!notes->src | 188 | goto out; |
222 | && symbol__alloc_hist(bx->from.sym) < 0) | 189 | |
223 | goto out; | 190 | err = addr_map_symbol__inc_samples(&bx->to, evsel->idx); |
224 | 191 | if (err) | |
225 | err = symbol__inc_addr_samples(bx->from.sym, | 192 | goto out; |
226 | bx->from.map, | ||
227 | evsel->idx, | ||
228 | bx->from.al_addr); | ||
229 | if (err) | ||
230 | goto out; | ||
231 | } | ||
232 | 193 | ||
233 | if (bx->to.sym && use_browser == 1 && sort__has_sym) { | ||
234 | notes = symbol__annotation(bx->to.sym); | ||
235 | if (!notes->src | ||
236 | && symbol__alloc_hist(bx->to.sym) < 0) | ||
237 | goto out; | ||
238 | |||
239 | err = symbol__inc_addr_samples(bx->to.sym, | ||
240 | bx->to.map, | ||
241 | evsel->idx, | ||
242 | bx->to.al_addr); | ||
243 | if (err) | ||
244 | goto out; | ||
245 | } | ||
246 | evsel->hists.stats.total_period += 1; | 194 | evsel->hists.stats.total_period += 1; |
247 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 195 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
248 | } else | 196 | } else |
@@ -254,24 +202,16 @@ out: | |||
254 | return err; | 202 | return err; |
255 | } | 203 | } |
256 | 204 | ||
257 | static int perf_evsel__add_hist_entry(struct perf_tool *tool, | 205 | static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evsel, |
258 | struct perf_evsel *evsel, | 206 | struct addr_location *al, struct perf_sample *sample) |
259 | struct addr_location *al, | ||
260 | struct perf_sample *sample, | ||
261 | struct machine *machine) | ||
262 | { | 207 | { |
263 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 208 | struct report *rep = container_of(tool, struct report, tool); |
264 | struct symbol *parent = NULL; | 209 | struct symbol *parent = NULL; |
265 | int err = 0; | ||
266 | struct hist_entry *he; | 210 | struct hist_entry *he; |
211 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
267 | 212 | ||
268 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { | 213 | if (err) |
269 | err = machine__resolve_callchain(machine, evsel, al->thread, | 214 | return err; |
270 | sample, &parent, al, | ||
271 | rep->max_stack); | ||
272 | if (err) | ||
273 | return err; | ||
274 | } | ||
275 | 215 | ||
276 | he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, | 216 | he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, |
277 | sample->period, sample->weight, | 217 | sample->period, sample->weight, |
@@ -279,30 +219,11 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool, | |||
279 | if (he == NULL) | 219 | if (he == NULL) |
280 | return -ENOMEM; | 220 | return -ENOMEM; |
281 | 221 | ||
282 | if (symbol_conf.use_callchain) { | 222 | err = hist_entry__append_callchain(he, sample); |
283 | err = callchain_append(he->callchain, | 223 | if (err) |
284 | &callchain_cursor, | 224 | goto out; |
285 | sample->period); | ||
286 | if (err) | ||
287 | return err; | ||
288 | } | ||
289 | /* | ||
290 | * Only in the TUI browser we are doing integrated annotation, | ||
291 | * so we don't allocated the extra space needed because the stdio | ||
292 | * code will not use it. | ||
293 | */ | ||
294 | if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) { | ||
295 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
296 | |||
297 | assert(evsel != NULL); | ||
298 | |||
299 | err = -ENOMEM; | ||
300 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
301 | goto out; | ||
302 | |||
303 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
304 | } | ||
305 | 225 | ||
226 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
306 | evsel->hists.stats.total_period += sample->period; | 227 | evsel->hists.stats.total_period += sample->period; |
307 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 228 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
308 | out: | 229 | out: |
@@ -316,13 +237,13 @@ static int process_sample_event(struct perf_tool *tool, | |||
316 | struct perf_evsel *evsel, | 237 | struct perf_evsel *evsel, |
317 | struct machine *machine) | 238 | struct machine *machine) |
318 | { | 239 | { |
319 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 240 | struct report *rep = container_of(tool, struct report, tool); |
320 | struct addr_location al; | 241 | struct addr_location al; |
321 | int ret; | 242 | int ret; |
322 | 243 | ||
323 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { | 244 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { |
324 | fprintf(stderr, "problem processing %d event, skipping it.\n", | 245 | pr_debug("problem processing %d event, skipping it.\n", |
325 | event->header.type); | 246 | event->header.type); |
326 | return -1; | 247 | return -1; |
327 | } | 248 | } |
328 | 249 | ||
@@ -333,21 +254,18 @@ static int process_sample_event(struct perf_tool *tool, | |||
333 | return 0; | 254 | return 0; |
334 | 255 | ||
335 | if (sort__mode == SORT_MODE__BRANCH) { | 256 | if (sort__mode == SORT_MODE__BRANCH) { |
336 | ret = perf_report__add_branch_hist_entry(tool, &al, sample, | 257 | ret = report__add_branch_hist_entry(tool, &al, sample, evsel); |
337 | evsel, machine); | ||
338 | if (ret < 0) | 258 | if (ret < 0) |
339 | pr_debug("problem adding lbr entry, skipping event\n"); | 259 | pr_debug("problem adding lbr entry, skipping event\n"); |
340 | } else if (rep->mem_mode == 1) { | 260 | } else if (rep->mem_mode == 1) { |
341 | ret = perf_report__add_mem_hist_entry(tool, &al, sample, | 261 | ret = report__add_mem_hist_entry(tool, &al, sample, evsel, event); |
342 | evsel, machine, event); | ||
343 | if (ret < 0) | 262 | if (ret < 0) |
344 | pr_debug("problem adding mem entry, skipping event\n"); | 263 | pr_debug("problem adding mem entry, skipping event\n"); |
345 | } else { | 264 | } else { |
346 | if (al.map != NULL) | 265 | if (al.map != NULL) |
347 | al.map->dso->hit = 1; | 266 | al.map->dso->hit = 1; |
348 | 267 | ||
349 | ret = perf_evsel__add_hist_entry(tool, evsel, &al, sample, | 268 | ret = report__add_hist_entry(tool, evsel, &al, sample); |
350 | machine); | ||
351 | if (ret < 0) | 269 | if (ret < 0) |
352 | pr_debug("problem incrementing symbol period, skipping event\n"); | 270 | pr_debug("problem incrementing symbol period, skipping event\n"); |
353 | } | 271 | } |
@@ -360,7 +278,7 @@ static int process_read_event(struct perf_tool *tool, | |||
360 | struct perf_evsel *evsel, | 278 | struct perf_evsel *evsel, |
361 | struct machine *machine __maybe_unused) | 279 | struct machine *machine __maybe_unused) |
362 | { | 280 | { |
363 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 281 | struct report *rep = container_of(tool, struct report, tool); |
364 | 282 | ||
365 | if (rep->show_threads) { | 283 | if (rep->show_threads) { |
366 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; | 284 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; |
@@ -379,7 +297,7 @@ static int process_read_event(struct perf_tool *tool, | |||
379 | } | 297 | } |
380 | 298 | ||
381 | /* For pipe mode, sample_type is not currently set */ | 299 | /* For pipe mode, sample_type is not currently set */ |
382 | static int perf_report__setup_sample_type(struct perf_report *rep) | 300 | static int report__setup_sample_type(struct report *rep) |
383 | { | 301 | { |
384 | struct perf_session *session = rep->session; | 302 | struct perf_session *session = rep->session; |
385 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); | 303 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); |
@@ -424,8 +342,7 @@ static void sig_handler(int sig __maybe_unused) | |||
424 | session_done = 1; | 342 | session_done = 1; |
425 | } | 343 | } |
426 | 344 | ||
427 | static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, | 345 | static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep, |
428 | struct hists *hists, | ||
429 | const char *evname, FILE *fp) | 346 | const char *evname, FILE *fp) |
430 | { | 347 | { |
431 | size_t ret; | 348 | size_t ret; |
@@ -462,7 +379,7 @@ static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, | |||
462 | } | 379 | } |
463 | 380 | ||
464 | static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | 381 | static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, |
465 | struct perf_report *rep, | 382 | struct report *rep, |
466 | const char *help) | 383 | const char *help) |
467 | { | 384 | { |
468 | struct perf_evsel *pos; | 385 | struct perf_evsel *pos; |
@@ -475,7 +392,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
475 | !perf_evsel__is_group_leader(pos)) | 392 | !perf_evsel__is_group_leader(pos)) |
476 | continue; | 393 | continue; |
477 | 394 | ||
478 | hists__fprintf_nr_sample_events(rep, hists, evname, stdout); | 395 | hists__fprintf_nr_sample_events(hists, rep, evname, stdout); |
479 | hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); | 396 | hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); |
480 | fprintf(stdout, "\n\n"); | 397 | fprintf(stdout, "\n\n"); |
481 | } | 398 | } |
@@ -495,7 +412,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
495 | return 0; | 412 | return 0; |
496 | } | 413 | } |
497 | 414 | ||
498 | static int __cmd_report(struct perf_report *rep) | 415 | static int __cmd_report(struct report *rep) |
499 | { | 416 | { |
500 | int ret = -EINVAL; | 417 | int ret = -EINVAL; |
501 | u64 nr_samples; | 418 | u64 nr_samples; |
@@ -519,7 +436,7 @@ static int __cmd_report(struct perf_report *rep) | |||
519 | if (rep->show_threads) | 436 | if (rep->show_threads) |
520 | perf_read_values_init(&rep->show_threads_values); | 437 | perf_read_values_init(&rep->show_threads_values); |
521 | 438 | ||
522 | ret = perf_report__setup_sample_type(rep); | 439 | ret = report__setup_sample_type(rep); |
523 | if (ret) | 440 | if (ret) |
524 | return ret; | 441 | return ret; |
525 | 442 | ||
@@ -552,15 +469,17 @@ static int __cmd_report(struct perf_report *rep) | |||
552 | desc); | 469 | desc); |
553 | } | 470 | } |
554 | 471 | ||
555 | if (verbose > 3) | 472 | if (use_browser == 0) { |
556 | perf_session__fprintf(session, stdout); | 473 | if (verbose > 3) |
474 | perf_session__fprintf(session, stdout); | ||
557 | 475 | ||
558 | if (verbose > 2) | 476 | if (verbose > 2) |
559 | perf_session__fprintf_dsos(session, stdout); | 477 | perf_session__fprintf_dsos(session, stdout); |
560 | 478 | ||
561 | if (dump_trace) { | 479 | if (dump_trace) { |
562 | perf_session__fprintf_nr_events(session, stdout); | 480 | perf_session__fprintf_nr_events(session, stdout); |
563 | return 0; | 481 | return 0; |
482 | } | ||
564 | } | 483 | } |
565 | 484 | ||
566 | nr_samples = 0; | 485 | nr_samples = 0; |
@@ -638,7 +557,7 @@ static int __cmd_report(struct perf_report *rep) | |||
638 | static int | 557 | static int |
639 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) | 558 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) |
640 | { | 559 | { |
641 | struct perf_report *rep = (struct perf_report *)opt->value; | 560 | struct report *rep = (struct report *)opt->value; |
642 | char *tok, *tok2; | 561 | char *tok, *tok2; |
643 | char *endptr; | 562 | char *endptr; |
644 | 563 | ||
@@ -720,7 +639,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) | |||
720 | return -1; | 639 | return -1; |
721 | setup: | 640 | setup: |
722 | if (callchain_register_param(&callchain_param) < 0) { | 641 | if (callchain_register_param(&callchain_param) < 0) { |
723 | fprintf(stderr, "Can't register callchain params\n"); | 642 | pr_err("Can't register callchain params\n"); |
724 | return -1; | 643 | return -1; |
725 | } | 644 | } |
726 | return 0; | 645 | return 0; |
@@ -758,7 +677,7 @@ static int | |||
758 | parse_percent_limit(const struct option *opt, const char *str, | 677 | parse_percent_limit(const struct option *opt, const char *str, |
759 | int unset __maybe_unused) | 678 | int unset __maybe_unused) |
760 | { | 679 | { |
761 | struct perf_report *rep = opt->value; | 680 | struct report *rep = opt->value; |
762 | 681 | ||
763 | rep->min_percent = strtof(str, NULL); | 682 | rep->min_percent = strtof(str, NULL); |
764 | return 0; | 683 | return 0; |
@@ -776,7 +695,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
776 | "perf report [<options>]", | 695 | "perf report [<options>]", |
777 | NULL | 696 | NULL |
778 | }; | 697 | }; |
779 | struct perf_report report = { | 698 | struct report report = { |
780 | .tool = { | 699 | .tool = { |
781 | .sample = process_sample_event, | 700 | .sample = process_sample_event, |
782 | .mmap = perf_event__process_mmap, | 701 | .mmap = perf_event__process_mmap, |
@@ -892,7 +811,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
892 | .mode = PERF_DATA_MODE_READ, | 811 | .mode = PERF_DATA_MODE_READ, |
893 | }; | 812 | }; |
894 | 813 | ||
895 | perf_config(perf_report_config, &report); | 814 | perf_config(report__config, &report); |
896 | 815 | ||
897 | argc = parse_options(argc, argv, options, report_usage, 0); | 816 | argc = parse_options(argc, argv, options, report_usage, 0); |
898 | 817 | ||
@@ -942,7 +861,7 @@ repeat: | |||
942 | } | 861 | } |
943 | if (report.mem_mode) { | 862 | if (report.mem_mode) { |
944 | if (sort__mode == SORT_MODE__BRANCH) { | 863 | if (sort__mode == SORT_MODE__BRANCH) { |
945 | fprintf(stderr, "branch and mem mode incompatible\n"); | 864 | pr_err("branch and mem mode incompatible\n"); |
946 | goto error; | 865 | goto error; |
947 | } | 866 | } |
948 | sort__mode = SORT_MODE__MEMORY; | 867 | sort__mode = SORT_MODE__MEMORY; |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 0f3c65518a2c..6a76a07b6789 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -469,7 +469,7 @@ static void *thread_func(void *ctx) | |||
469 | char comm2[22]; | 469 | char comm2[22]; |
470 | int fd; | 470 | int fd; |
471 | 471 | ||
472 | free(parms); | 472 | zfree(&parms); |
473 | 473 | ||
474 | sprintf(comm2, ":%s", this_task->comm); | 474 | sprintf(comm2, ":%s", this_task->comm); |
475 | prctl(PR_SET_NAME, comm2); | 475 | prctl(PR_SET_NAME, comm2); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f8ab125aac48..6040000bdfa6 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -423,7 +423,6 @@ static void print_sample_addr(union perf_event *event, | |||
423 | static void print_sample_bts(union perf_event *event, | 423 | static void print_sample_bts(union perf_event *event, |
424 | struct perf_sample *sample, | 424 | struct perf_sample *sample, |
425 | struct perf_evsel *evsel, | 425 | struct perf_evsel *evsel, |
426 | struct machine *machine, | ||
427 | struct thread *thread, | 426 | struct thread *thread, |
428 | struct addr_location *al) | 427 | struct addr_location *al) |
429 | { | 428 | { |
@@ -435,7 +434,7 @@ static void print_sample_bts(union perf_event *event, | |||
435 | printf(" "); | 434 | printf(" "); |
436 | else | 435 | else |
437 | printf("\n"); | 436 | printf("\n"); |
438 | perf_evsel__print_ip(evsel, sample, machine, al, | 437 | perf_evsel__print_ip(evsel, sample, al, |
439 | output[attr->type].print_ip_opts, | 438 | output[attr->type].print_ip_opts, |
440 | PERF_MAX_STACK_DEPTH); | 439 | PERF_MAX_STACK_DEPTH); |
441 | } | 440 | } |
@@ -446,14 +445,13 @@ static void print_sample_bts(union perf_event *event, | |||
446 | if (PRINT_FIELD(ADDR) || | 445 | if (PRINT_FIELD(ADDR) || |
447 | ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && | 446 | ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && |
448 | !output[attr->type].user_set)) | 447 | !output[attr->type].user_set)) |
449 | print_sample_addr(event, sample, machine, thread, attr); | 448 | print_sample_addr(event, sample, al->machine, thread, attr); |
450 | 449 | ||
451 | printf("\n"); | 450 | printf("\n"); |
452 | } | 451 | } |
453 | 452 | ||
454 | static void process_event(union perf_event *event, struct perf_sample *sample, | 453 | static void process_event(union perf_event *event, struct perf_sample *sample, |
455 | struct perf_evsel *evsel, struct machine *machine, | 454 | struct perf_evsel *evsel, struct thread *thread, |
456 | struct thread *thread, | ||
457 | struct addr_location *al) | 455 | struct addr_location *al) |
458 | { | 456 | { |
459 | struct perf_event_attr *attr = &evsel->attr; | 457 | struct perf_event_attr *attr = &evsel->attr; |
@@ -469,7 +467,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
469 | } | 467 | } |
470 | 468 | ||
471 | if (is_bts_event(attr)) { | 469 | if (is_bts_event(attr)) { |
472 | print_sample_bts(event, sample, evsel, machine, thread, al); | 470 | print_sample_bts(event, sample, evsel, thread, al); |
473 | return; | 471 | return; |
474 | } | 472 | } |
475 | 473 | ||
@@ -477,7 +475,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
477 | event_format__print(evsel->tp_format, sample->cpu, | 475 | event_format__print(evsel->tp_format, sample->cpu, |
478 | sample->raw_data, sample->raw_size); | 476 | sample->raw_data, sample->raw_size); |
479 | if (PRINT_FIELD(ADDR)) | 477 | if (PRINT_FIELD(ADDR)) |
480 | print_sample_addr(event, sample, machine, thread, attr); | 478 | print_sample_addr(event, sample, al->machine, thread, attr); |
481 | 479 | ||
482 | if (PRINT_FIELD(IP)) { | 480 | if (PRINT_FIELD(IP)) { |
483 | if (!symbol_conf.use_callchain) | 481 | if (!symbol_conf.use_callchain) |
@@ -485,7 +483,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
485 | else | 483 | else |
486 | printf("\n"); | 484 | printf("\n"); |
487 | 485 | ||
488 | perf_evsel__print_ip(evsel, sample, machine, al, | 486 | perf_evsel__print_ip(evsel, sample, al, |
489 | output[attr->type].print_ip_opts, | 487 | output[attr->type].print_ip_opts, |
490 | PERF_MAX_STACK_DEPTH); | 488 | PERF_MAX_STACK_DEPTH); |
491 | } | 489 | } |
@@ -574,7 +572,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
574 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) | 572 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) |
575 | return 0; | 573 | return 0; |
576 | 574 | ||
577 | scripting_ops->process_event(event, sample, evsel, machine, thread, &al); | 575 | scripting_ops->process_event(event, sample, evsel, thread, &al); |
578 | 576 | ||
579 | evsel->hists.stats.total_period += sample->period; | 577 | evsel->hists.stats.total_period += sample->period; |
580 | return 0; | 578 | return 0; |
@@ -1104,9 +1102,9 @@ static struct script_desc *script_desc__new(const char *name) | |||
1104 | 1102 | ||
1105 | static void script_desc__delete(struct script_desc *s) | 1103 | static void script_desc__delete(struct script_desc *s) |
1106 | { | 1104 | { |
1107 | free(s->name); | 1105 | zfree(&s->name); |
1108 | free(s->half_liner); | 1106 | zfree(&s->half_liner); |
1109 | free(s->args); | 1107 | zfree(&s->args); |
1110 | free(s); | 1108 | free(s); |
1111 | } | 1109 | } |
1112 | 1110 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dab98b50c9fe..106a5e5b7842 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -185,8 +185,7 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) | |||
185 | 185 | ||
186 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) | 186 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) |
187 | { | 187 | { |
188 | free(evsel->priv); | 188 | zfree(&evsel->priv); |
189 | evsel->priv = NULL; | ||
190 | } | 189 | } |
191 | 190 | ||
192 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) | 191 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) |
@@ -208,8 +207,7 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) | |||
208 | 207 | ||
209 | static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) | 208 | static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) |
210 | { | 209 | { |
211 | free(evsel->prev_raw_counts); | 210 | zfree(&evsel->prev_raw_counts); |
212 | evsel->prev_raw_counts = NULL; | ||
213 | } | 211 | } |
214 | 212 | ||
215 | static void perf_evlist__free_stats(struct perf_evlist *evlist) | 213 | static void perf_evlist__free_stats(struct perf_evlist *evlist) |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 20d4212fa337..652af0b66a62 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
@@ -488,8 +488,7 @@ static const char *cat_backtrace(union perf_event *event, | |||
488 | * It seems the callchain is corrupted. | 488 | * It seems the callchain is corrupted. |
489 | * Discard all. | 489 | * Discard all. |
490 | */ | 490 | */ |
491 | free(p); | 491 | zfree(&p); |
492 | p = NULL; | ||
493 | goto exit; | 492 | goto exit; |
494 | } | 493 | } |
495 | continue; | 494 | continue; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 03d37a76c612..172e91a9ce62 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -189,21 +189,18 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
189 | if (pthread_mutex_trylock(¬es->lock)) | 189 | if (pthread_mutex_trylock(¬es->lock)) |
190 | return; | 190 | return; |
191 | 191 | ||
192 | if (notes->src == NULL && symbol__alloc_hist(sym) < 0) { | ||
193 | pthread_mutex_unlock(¬es->lock); | ||
194 | pr_err("Not enough memory for annotating '%s' symbol!\n", | ||
195 | sym->name); | ||
196 | sleep(1); | ||
197 | return; | ||
198 | } | ||
199 | |||
200 | ip = he->ms.map->map_ip(he->ms.map, ip); | 192 | ip = he->ms.map->map_ip(he->ms.map, ip); |
201 | err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); | 193 | err = hist_entry__inc_addr_samples(he, counter, ip); |
202 | 194 | ||
203 | pthread_mutex_unlock(¬es->lock); | 195 | pthread_mutex_unlock(¬es->lock); |
204 | 196 | ||
205 | if (err == -ERANGE && !he->ms.map->erange_warned) | 197 | if (err == -ERANGE && !he->ms.map->erange_warned) |
206 | ui__warn_map_erange(he->ms.map, sym, ip); | 198 | ui__warn_map_erange(he->ms.map, sym, ip); |
199 | else if (err == -ENOMEM) { | ||
200 | pr_err("Not enough memory for annotating '%s' symbol!\n", | ||
201 | sym->name); | ||
202 | sleep(1); | ||
203 | } | ||
207 | } | 204 | } |
208 | 205 | ||
209 | static void perf_top__show_details(struct perf_top *top) | 206 | static void perf_top__show_details(struct perf_top *top) |
@@ -857,7 +854,7 @@ static int perf_top__start_counters(struct perf_top *top) | |||
857 | char msg[512]; | 854 | char msg[512]; |
858 | struct perf_evsel *counter; | 855 | struct perf_evsel *counter; |
859 | struct perf_evlist *evlist = top->evlist; | 856 | struct perf_evlist *evlist = top->evlist; |
860 | struct perf_record_opts *opts = &top->record_opts; | 857 | struct record_opts *opts = &top->record_opts; |
861 | 858 | ||
862 | perf_evlist__config(evlist, opts); | 859 | perf_evlist__config(evlist, opts); |
863 | 860 | ||
@@ -909,7 +906,7 @@ static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused) | |||
909 | 906 | ||
910 | static int __cmd_top(struct perf_top *top) | 907 | static int __cmd_top(struct perf_top *top) |
911 | { | 908 | { |
912 | struct perf_record_opts *opts = &top->record_opts; | 909 | struct record_opts *opts = &top->record_opts; |
913 | pthread_t thread; | 910 | pthread_t thread; |
914 | int ret; | 911 | int ret; |
915 | 912 | ||
@@ -1031,7 +1028,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1031 | .max_stack = PERF_MAX_STACK_DEPTH, | 1028 | .max_stack = PERF_MAX_STACK_DEPTH, |
1032 | .sym_pcnt_filter = 5, | 1029 | .sym_pcnt_filter = 5, |
1033 | }; | 1030 | }; |
1034 | struct perf_record_opts *opts = &top.record_opts; | 1031 | struct record_opts *opts = &top.record_opts; |
1035 | struct target *target = &opts->target; | 1032 | struct target *target = &opts->target; |
1036 | const struct option options[] = { | 1033 | const struct option options[] = { |
1037 | OPT_CALLBACK('e', "event", &top.evlist, "event", | 1034 | OPT_CALLBACK('e', "event", &top.evlist, "event", |
@@ -1182,7 +1179,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1182 | if (top.delay_secs < 1) | 1179 | if (top.delay_secs < 1) |
1183 | top.delay_secs = 1; | 1180 | top.delay_secs = 1; |
1184 | 1181 | ||
1185 | if (perf_record_opts__config(opts)) { | 1182 | if (record_opts__config(opts)) { |
1186 | status = -EINVAL; | 1183 | status = -EINVAL; |
1187 | goto out_delete_maps; | 1184 | goto out_delete_maps; |
1188 | } | 1185 | } |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 56bbca5bc2dc..c5b4bc51175c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -146,8 +146,7 @@ static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel, | |||
146 | 146 | ||
147 | static void perf_evsel__delete_priv(struct perf_evsel *evsel) | 147 | static void perf_evsel__delete_priv(struct perf_evsel *evsel) |
148 | { | 148 | { |
149 | free(evsel->priv); | 149 | zfree(&evsel->priv); |
150 | evsel->priv = NULL; | ||
151 | perf_evsel__delete(evsel); | 150 | perf_evsel__delete(evsel); |
152 | } | 151 | } |
153 | 152 | ||
@@ -165,8 +164,7 @@ static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler) | |||
165 | return -ENOMEM; | 164 | return -ENOMEM; |
166 | 165 | ||
167 | out_delete: | 166 | out_delete: |
168 | free(evsel->priv); | 167 | zfree(&evsel->priv); |
169 | evsel->priv = NULL; | ||
170 | return -ENOENT; | 168 | return -ENOENT; |
171 | } | 169 | } |
172 | 170 | ||
@@ -1159,7 +1157,7 @@ struct trace { | |||
1159 | int max; | 1157 | int max; |
1160 | struct syscall *table; | 1158 | struct syscall *table; |
1161 | } syscalls; | 1159 | } syscalls; |
1162 | struct perf_record_opts opts; | 1160 | struct record_opts opts; |
1163 | struct machine *host; | 1161 | struct machine *host; |
1164 | u64 base_time; | 1162 | u64 base_time; |
1165 | bool full_time; | 1163 | bool full_time; |
@@ -1278,10 +1276,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, | |||
1278 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); | 1276 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); |
1279 | struct thread_trace *ttrace = arg->thread->priv; | 1277 | struct thread_trace *ttrace = arg->thread->priv; |
1280 | 1278 | ||
1281 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) { | 1279 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) |
1282 | free(ttrace->paths.table[fd]); | 1280 | zfree(&ttrace->paths.table[fd]); |
1283 | ttrace->paths.table[fd] = NULL; | ||
1284 | } | ||
1285 | 1281 | ||
1286 | return printed; | 1282 | return printed; |
1287 | } | 1283 | } |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5a1f4df3c3a8..14faeeb0d752 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -126,7 +126,7 @@ endif | |||
126 | 126 | ||
127 | feature_check = $(eval $(feature_check_code)) | 127 | feature_check = $(eval $(feature_check_code)) |
128 | define feature_check_code | 128 | define feature_check_code |
129 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) | 129 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) |
130 | endef | 130 | endef |
131 | 131 | ||
132 | feature_set = $(eval $(feature_set_code)) | 132 | feature_set = $(eval $(feature_set_code)) |
@@ -173,7 +173,7 @@ CORE_FEATURE_TESTS = \ | |||
173 | # to skip the print-out of the long features list if the file | 173 | # to skip the print-out of the long features list if the file |
174 | # existed before and after it was built: | 174 | # existed before and after it was built: |
175 | # | 175 | # |
176 | ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),) | 176 | ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all.bin),) |
177 | test-all-failed := 1 | 177 | test-all-failed := 1 |
178 | else | 178 | else |
179 | test-all-failed := 0 | 179 | test-all-failed := 0 |
@@ -203,7 +203,7 @@ ifeq ($(feature-all), 1) | |||
203 | # | 203 | # |
204 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) | 204 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) |
205 | else | 205 | else |
206 | $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) | 206 | $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(CORE_FEATURE_TESTS)) >/dev/null 2>&1) |
207 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) | 207 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) |
208 | endif | 208 | endif |
209 | 209 | ||
diff --git a/tools/perf/config/feature-checks/.gitignore b/tools/perf/config/feature-checks/.gitignore new file mode 100644 index 000000000000..80f3da0c3515 --- /dev/null +++ b/tools/perf/config/feature-checks/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | *.d | ||
2 | *.bin | ||
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index bc86462e80a2..7cf6fcdacebe 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile | |||
@@ -1,90 +1,90 @@ | |||
1 | 1 | ||
2 | FILES= \ | 2 | FILES= \ |
3 | test-all \ | 3 | test-all.bin \ |
4 | test-backtrace \ | 4 | test-backtrace.bin \ |
5 | test-bionic \ | 5 | test-bionic.bin \ |
6 | test-dwarf \ | 6 | test-dwarf.bin \ |
7 | test-fortify-source \ | 7 | test-fortify-source.bin \ |
8 | test-glibc \ | 8 | test-glibc.bin \ |
9 | test-gtk2 \ | 9 | test-gtk2.bin \ |
10 | test-gtk2-infobar \ | 10 | test-gtk2-infobar.bin \ |
11 | test-hello \ | 11 | test-hello.bin \ |
12 | test-libaudit \ | 12 | test-libaudit.bin \ |
13 | test-libbfd \ | 13 | test-libbfd.bin \ |
14 | test-liberty \ | 14 | test-liberty.bin \ |
15 | test-liberty-z \ | 15 | test-liberty-z.bin \ |
16 | test-cplus-demangle \ | 16 | test-cplus-demangle.bin \ |
17 | test-libelf \ | 17 | test-libelf.bin \ |
18 | test-libelf-getphdrnum \ | 18 | test-libelf-getphdrnum.bin \ |
19 | test-libelf-mmap \ | 19 | test-libelf-mmap.bin \ |
20 | test-libnuma \ | 20 | test-libnuma.bin \ |
21 | test-libperl \ | 21 | test-libperl.bin \ |
22 | test-libpython \ | 22 | test-libpython.bin \ |
23 | test-libpython-version \ | 23 | test-libpython-version.bin \ |
24 | test-libslang \ | 24 | test-libslang.bin \ |
25 | test-libunwind \ | 25 | test-libunwind.bin \ |
26 | test-libunwind-debug-frame \ | 26 | test-libunwind-debug-frame.bin \ |
27 | test-on-exit \ | 27 | test-on-exit.bin \ |
28 | test-stackprotector-all \ | 28 | test-stackprotector-all.bin \ |
29 | test-timerfd | 29 | test-timerfd.bin |
30 | 30 | ||
31 | CC := $(CC) -MD | 31 | CC := $(CC) -MD |
32 | 32 | ||
33 | all: $(FILES) | 33 | all: $(FILES) |
34 | 34 | ||
35 | BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS) | 35 | BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS) |
36 | 36 | ||
37 | ############################### | 37 | ############################### |
38 | 38 | ||
39 | test-all: | 39 | test-all.bin: |
40 | $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl | 40 | $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl |
41 | 41 | ||
42 | test-hello: | 42 | test-hello.bin: |
43 | $(BUILD) | 43 | $(BUILD) |
44 | 44 | ||
45 | test-stackprotector-all: | 45 | test-stackprotector-all.bin: |
46 | $(BUILD) -Werror -fstack-protector-all | 46 | $(BUILD) -Werror -fstack-protector-all |
47 | 47 | ||
48 | test-fortify-source: | 48 | test-fortify-source.bin: |
49 | $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 | 49 | $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 |
50 | 50 | ||
51 | test-bionic: | 51 | test-bionic.bin: |
52 | $(BUILD) | 52 | $(BUILD) |
53 | 53 | ||
54 | test-libelf: | 54 | test-libelf.bin: |
55 | $(BUILD) -lelf | 55 | $(BUILD) -lelf |
56 | 56 | ||
57 | test-glibc: | 57 | test-glibc.bin: |
58 | $(BUILD) | 58 | $(BUILD) |
59 | 59 | ||
60 | test-dwarf: | 60 | test-dwarf.bin: |
61 | $(BUILD) -ldw | 61 | $(BUILD) -ldw |
62 | 62 | ||
63 | test-libelf-mmap: | 63 | test-libelf-mmap.bin: |
64 | $(BUILD) -lelf | 64 | $(BUILD) -lelf |
65 | 65 | ||
66 | test-libelf-getphdrnum: | 66 | test-libelf-getphdrnum.bin: |
67 | $(BUILD) -lelf | 67 | $(BUILD) -lelf |
68 | 68 | ||
69 | test-libnuma: | 69 | test-libnuma.bin: |
70 | $(BUILD) -lnuma | 70 | $(BUILD) -lnuma |
71 | 71 | ||
72 | test-libunwind: | 72 | test-libunwind.bin: |
73 | $(BUILD) -lelf | 73 | $(BUILD) -lelf |
74 | 74 | ||
75 | test-libunwind-debug-frame: | 75 | test-libunwind-debug-frame.bin: |
76 | $(BUILD) -lelf | 76 | $(BUILD) -lelf |
77 | 77 | ||
78 | test-libaudit: | 78 | test-libaudit.bin: |
79 | $(BUILD) -laudit | 79 | $(BUILD) -laudit |
80 | 80 | ||
81 | test-libslang: | 81 | test-libslang.bin: |
82 | $(BUILD) -I/usr/include/slang -lslang | 82 | $(BUILD) -I/usr/include/slang -lslang |
83 | 83 | ||
84 | test-gtk2: | 84 | test-gtk2.bin: |
85 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) | 85 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) |
86 | 86 | ||
87 | test-gtk2-infobar: | 87 | test-gtk2-infobar.bin: |
88 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) | 88 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) |
89 | 89 | ||
90 | grep-libs = $(filter -l%,$(1)) | 90 | grep-libs = $(filter -l%,$(1)) |
@@ -96,7 +96,7 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) | |||
96 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 96 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
97 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) | 97 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) |
98 | 98 | ||
99 | test-libperl: | 99 | test-libperl.bin: |
100 | $(BUILD) $(FLAGS_PERL_EMBED) | 100 | $(BUILD) $(FLAGS_PERL_EMBED) |
101 | 101 | ||
102 | override PYTHON := python | 102 | override PYTHON := python |
@@ -113,31 +113,31 @@ PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) | |||
113 | PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) | 113 | PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) |
114 | FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) | 114 | FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) |
115 | 115 | ||
116 | test-libpython: | 116 | test-libpython.bin: |
117 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 117 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
118 | 118 | ||
119 | test-libpython-version: | 119 | test-libpython-version.bin: |
120 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 120 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
121 | 121 | ||
122 | test-libbfd: | 122 | test-libbfd.bin: |
123 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl | 123 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl |
124 | 124 | ||
125 | test-liberty: | 125 | test-liberty.bin: |
126 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty | 126 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty |
127 | 127 | ||
128 | test-liberty-z: | 128 | test-liberty-z.bin: |
129 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz | 129 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz |
130 | 130 | ||
131 | test-cplus-demangle: | 131 | test-cplus-demangle.bin: |
132 | $(BUILD) -liberty | 132 | $(BUILD) -liberty |
133 | 133 | ||
134 | test-on-exit: | 134 | test-on-exit.bin: |
135 | $(BUILD) | 135 | $(BUILD) |
136 | 136 | ||
137 | test-backtrace: | 137 | test-backtrace.bin: |
138 | $(BUILD) | 138 | $(BUILD) |
139 | 139 | ||
140 | test-timerfd: | 140 | test-timerfd.bin: |
141 | $(BUILD) | 141 | $(BUILD) |
142 | 142 | ||
143 | -include *.d | 143 | -include *.d |
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index f168debc5be2..4d985e0f03f5 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak | |||
@@ -178,10 +178,3 @@ endef | |||
178 | _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) | 178 | _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) |
179 | _gea_warn = $(warning The path '$(1)' is not executable.) | 179 | _gea_warn = $(warning The path '$(1)' is not executable.) |
180 | _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) | 180 | _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) |
181 | |||
182 | ifneq ($(findstring $(MAKEFLAGS),s),s) | ||
183 | ifneq ($(V),1) | ||
184 | QUIET_CLEAN = @printf ' CLEAN %s\n' $1; | ||
185 | QUIET_INSTALL = @printf ' INSTALL %s\n' $1; | ||
186 | endif | ||
187 | endif | ||
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index b23fed527514..b1cc84b01d5b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -247,7 +247,7 @@ enum perf_call_graph_mode { | |||
247 | CALLCHAIN_DWARF | 247 | CALLCHAIN_DWARF |
248 | }; | 248 | }; |
249 | 249 | ||
250 | struct perf_record_opts { | 250 | struct record_opts { |
251 | struct target target; | 251 | struct target target; |
252 | int call_graph; | 252 | int call_graph; |
253 | bool group; | 253 | bool group; |
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 85d4919dd623..4248d1e96848 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c | |||
@@ -391,7 +391,7 @@ static int do_test_code_reading(bool try_kcore) | |||
391 | struct machines machines; | 391 | struct machines machines; |
392 | struct machine *machine; | 392 | struct machine *machine; |
393 | struct thread *thread; | 393 | struct thread *thread; |
394 | struct perf_record_opts opts = { | 394 | struct record_opts opts = { |
395 | .mmap_pages = UINT_MAX, | 395 | .mmap_pages = UINT_MAX, |
396 | .user_freq = UINT_MAX, | 396 | .user_freq = UINT_MAX, |
397 | .user_interval = ULLONG_MAX, | 397 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 376c35608534..27eb75142b88 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c | |||
@@ -51,7 +51,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm) | |||
51 | */ | 51 | */ |
52 | int test__keep_tracking(void) | 52 | int test__keep_tracking(void) |
53 | { | 53 | { |
54 | struct perf_record_opts opts = { | 54 | struct record_opts opts = { |
55 | .mmap_pages = UINT_MAX, | 55 | .mmap_pages = UINT_MAX, |
56 | .user_freq = UINT_MAX, | 56 | .user_freq = UINT_MAX, |
57 | .user_interval = ULLONG_MAX, | 57 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 2ca0abf1b2b6..f641c35f2321 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make | |||
@@ -106,10 +106,36 @@ test_make_python_perf_so := test -f $(PERF)/python/perf.so | |||
106 | test_make_perf_o := test -f $(PERF)/perf.o | 106 | test_make_perf_o := test -f $(PERF)/perf.o |
107 | test_make_util_map_o := test -f $(PERF)/util/map.o | 107 | test_make_util_map_o := test -f $(PERF)/util/map.o |
108 | 108 | ||
109 | test_make_install := test -x $$TMP_DEST/bin/perf | 109 | define test_dest_files |
110 | test_make_install_O := $(test_make_install) | 110 | for file in $(1); do \ |
111 | test_make_install_bin := $(test_make_install) | 111 | if [ ! -x $$TMP_DEST/$$file ]; then \ |
112 | test_make_install_bin_O := $(test_make_install) | 112 | echo " failed to find: $$file"; \ |
113 | fi \ | ||
114 | done | ||
115 | endef | ||
116 | |||
117 | installed_files_bin := bin/perf | ||
118 | installed_files_bin += etc/bash_completion.d/perf | ||
119 | installed_files_bin += libexec/perf-core/perf-archive | ||
120 | |||
121 | installed_files_plugins := lib64/traceevent/plugins/plugin_cfg80211.so | ||
122 | installed_files_plugins += lib64/traceevent/plugins/plugin_scsi.so | ||
123 | installed_files_plugins += lib64/traceevent/plugins/plugin_xen.so | ||
124 | installed_files_plugins += lib64/traceevent/plugins/plugin_function.so | ||
125 | installed_files_plugins += lib64/traceevent/plugins/plugin_sched_switch.so | ||
126 | installed_files_plugins += lib64/traceevent/plugins/plugin_mac80211.so | ||
127 | installed_files_plugins += lib64/traceevent/plugins/plugin_kvm.so | ||
128 | installed_files_plugins += lib64/traceevent/plugins/plugin_kmem.so | ||
129 | installed_files_plugins += lib64/traceevent/plugins/plugin_hrtimer.so | ||
130 | installed_files_plugins += lib64/traceevent/plugins/plugin_jbd2.so | ||
131 | |||
132 | installed_files_all := $(installed_files_bin) | ||
133 | installed_files_all += $(installed_files_plugins) | ||
134 | |||
135 | test_make_install := $(call test_dest_files,$(installed_files_all)) | ||
136 | test_make_install_O := $(call test_dest_files,$(installed_files_all)) | ||
137 | test_make_install_bin := $(call test_dest_files,$(installed_files_bin)) | ||
138 | test_make_install_bin_O := $(call test_dest_files,$(installed_files_bin)) | ||
113 | 139 | ||
114 | # FIXME nothing gets installed | 140 | # FIXME nothing gets installed |
115 | test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1 | 141 | test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1 |
@@ -162,7 +188,7 @@ $(run): | |||
162 | cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \ | 188 | cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \ |
163 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ | 189 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ |
164 | ( eval $$cmd ) >> $@ 2>&1; \ | 190 | ( eval $$cmd ) >> $@ 2>&1; \ |
165 | echo " test: $(call test,$@)"; \ | 191 | echo " test: $(call test,$@)" >> $@ 2>&1; \ |
166 | $(call test,$@) && \ | 192 | $(call test,$@) && \ |
167 | rm -f $@ \ | 193 | rm -f $@ \ |
168 | rm -rf $$TMP_DEST | 194 | rm -rf $$TMP_DEST |
@@ -174,7 +200,7 @@ $(run_O): | |||
174 | cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \ | 200 | cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \ |
175 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ | 201 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ |
176 | ( eval $$cmd ) >> $@ 2>&1 && \ | 202 | ( eval $$cmd ) >> $@ 2>&1 && \ |
177 | echo " test: $(call test_O,$@)"; \ | 203 | echo " test: $(call test_O,$@)" >> $@ 2>&1; \ |
178 | $(call test_O,$@) && \ | 204 | $(call test_O,$@) && \ |
179 | rm -f $@ && \ | 205 | rm -f $@ && \ |
180 | rm -rf $$TMP_O \ | 206 | rm -rf $$TMP_O \ |
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 41cc0badb74b..774620a5aecb 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | int test__syscall_open_tp_fields(void) | 7 | int test__syscall_open_tp_fields(void) |
8 | { | 8 | { |
9 | struct perf_record_opts opts = { | 9 | struct record_opts opts = { |
10 | .target = { | 10 | .target = { |
11 | .uid = UINT_MAX, | 11 | .uid = UINT_MAX, |
12 | .uses_mmap = true, | 12 | .uses_mmap = true, |
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 93a62b06c3af..eeba562920e9 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c | |||
@@ -34,7 +34,7 @@ realloc: | |||
34 | 34 | ||
35 | int test__PERF_RECORD(void) | 35 | int test__PERF_RECORD(void) |
36 | { | 36 | { |
37 | struct perf_record_opts opts = { | 37 | struct record_opts opts = { |
38 | .target = { | 38 | .target = { |
39 | .uid = UINT_MAX, | 39 | .uid = UINT_MAX, |
40 | .uses_mmap = true, | 40 | .uses_mmap = true, |
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 4ca1b938f6a6..c6398b90e897 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c | |||
@@ -46,7 +46,7 @@ static u64 rdtsc(void) | |||
46 | */ | 46 | */ |
47 | int test__perf_time_to_tsc(void) | 47 | int test__perf_time_to_tsc(void) |
48 | { | 48 | { |
49 | struct perf_record_opts opts = { | 49 | struct record_opts opts = { |
50 | .mmap_pages = UINT_MAX, | 50 | .mmap_pages = UINT_MAX, |
51 | .user_freq = UINT_MAX, | 51 | .user_freq = UINT_MAX, |
52 | .user_interval = ULLONG_MAX, | 52 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index cbaa7af45513..d11541d4d7d7 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
@@ -256,8 +256,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title, | |||
256 | __ui_browser__show_title(browser, title); | 256 | __ui_browser__show_title(browser, title); |
257 | 257 | ||
258 | browser->title = title; | 258 | browser->title = title; |
259 | free(browser->helpline); | 259 | zfree(&browser->helpline); |
260 | browser->helpline = NULL; | ||
261 | 260 | ||
262 | va_start(ap, helpline); | 261 | va_start(ap, helpline); |
263 | err = vasprintf(&browser->helpline, helpline, ap); | 262 | err = vasprintf(&browser->helpline, helpline, ap); |
@@ -268,12 +267,11 @@ int ui_browser__show(struct ui_browser *browser, const char *title, | |||
268 | return err ? 0 : -1; | 267 | return err ? 0 : -1; |
269 | } | 268 | } |
270 | 269 | ||
271 | void ui_browser__hide(struct ui_browser *browser __maybe_unused) | 270 | void ui_browser__hide(struct ui_browser *browser) |
272 | { | 271 | { |
273 | pthread_mutex_lock(&ui__lock); | 272 | pthread_mutex_lock(&ui__lock); |
274 | ui_helpline__pop(); | 273 | ui_helpline__pop(); |
275 | free(browser->helpline); | 274 | zfree(&browser->helpline); |
276 | browser->helpline = NULL; | ||
277 | pthread_mutex_unlock(&ui__lock); | 275 | pthread_mutex_unlock(&ui__lock); |
278 | } | 276 | } |
279 | 277 | ||
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index 7d45d2f53601..118cca29dd26 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h | |||
@@ -59,6 +59,8 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text); | |||
59 | bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); | 59 | bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); |
60 | int ui_browser__input_window(const char *title, const char *text, char *input, | 60 | int ui_browser__input_window(const char *title, const char *text, char *input, |
61 | const char *exit_msg, int delay_sec); | 61 | const char *exit_msg, int delay_sec); |
62 | struct perf_session_env; | ||
63 | int tui__header_window(struct perf_session_env *env); | ||
62 | 64 | ||
63 | void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); | 65 | void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); |
64 | unsigned int ui_browser__argv_refresh(struct ui_browser *browser); | 66 | unsigned int ui_browser__argv_refresh(struct ui_browser *browser); |
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c new file mode 100644 index 000000000000..89c16b988618 --- /dev/null +++ b/tools/perf/ui/browsers/header.c | |||
@@ -0,0 +1,127 @@ | |||
1 | #include "util/cache.h" | ||
2 | #include "util/debug.h" | ||
3 | #include "ui/browser.h" | ||
4 | #include "ui/ui.h" | ||
5 | #include "ui/util.h" | ||
6 | #include "ui/libslang.h" | ||
7 | #include "util/header.h" | ||
8 | #include "util/session.h" | ||
9 | |||
10 | static void ui_browser__argv_write(struct ui_browser *browser, | ||
11 | void *entry, int row) | ||
12 | { | ||
13 | char **arg = entry; | ||
14 | char *str = *arg; | ||
15 | char empty[] = " "; | ||
16 | bool current_entry = ui_browser__is_current_entry(browser, row); | ||
17 | unsigned long offset = (unsigned long)browser->priv; | ||
18 | |||
19 | if (offset >= strlen(str)) | ||
20 | str = empty; | ||
21 | else | ||
22 | str = str + offset; | ||
23 | |||
24 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | ||
25 | HE_COLORSET_NORMAL); | ||
26 | |||
27 | slsmg_write_nstring(str, browser->width); | ||
28 | } | ||
29 | |||
30 | static int list_menu__run(struct ui_browser *menu) | ||
31 | { | ||
32 | int key; | ||
33 | unsigned long offset; | ||
34 | const char help[] = | ||
35 | "h/?/F1 Show this window\n" | ||
36 | "UP/DOWN/PGUP\n" | ||
37 | "PGDN/SPACE\n" | ||
38 | "LEFT/RIGHT Navigate\n" | ||
39 | "q/ESC/CTRL+C Exit browser"; | ||
40 | |||
41 | if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0) | ||
42 | return -1; | ||
43 | |||
44 | while (1) { | ||
45 | key = ui_browser__run(menu, 0); | ||
46 | |||
47 | switch (key) { | ||
48 | case K_RIGHT: | ||
49 | offset = (unsigned long)menu->priv; | ||
50 | offset += 10; | ||
51 | menu->priv = (void *)offset; | ||
52 | continue; | ||
53 | case K_LEFT: | ||
54 | offset = (unsigned long)menu->priv; | ||
55 | if (offset >= 10) | ||
56 | offset -= 10; | ||
57 | menu->priv = (void *)offset; | ||
58 | continue; | ||
59 | case K_F1: | ||
60 | case 'h': | ||
61 | case '?': | ||
62 | ui_browser__help_window(menu, help); | ||
63 | continue; | ||
64 | case K_ESC: | ||
65 | case 'q': | ||
66 | case CTRL('c'): | ||
67 | key = -1; | ||
68 | break; | ||
69 | default: | ||
70 | continue; | ||
71 | } | ||
72 | |||
73 | break; | ||
74 | } | ||
75 | |||
76 | ui_browser__hide(menu); | ||
77 | return key; | ||
78 | } | ||
79 | |||
80 | static int ui__list_menu(int argc, char * const argv[]) | ||
81 | { | ||
82 | struct ui_browser menu = { | ||
83 | .entries = (void *)argv, | ||
84 | .refresh = ui_browser__argv_refresh, | ||
85 | .seek = ui_browser__argv_seek, | ||
86 | .write = ui_browser__argv_write, | ||
87 | .nr_entries = argc, | ||
88 | }; | ||
89 | |||
90 | return list_menu__run(&menu); | ||
91 | } | ||
92 | |||
93 | int tui__header_window(struct perf_session_env *env) | ||
94 | { | ||
95 | int i, argc = 0; | ||
96 | char **argv; | ||
97 | struct perf_session *session; | ||
98 | char *ptr, *pos; | ||
99 | size_t size; | ||
100 | FILE *fp = open_memstream(&ptr, &size); | ||
101 | |||
102 | session = container_of(env, struct perf_session, header.env); | ||
103 | perf_header__fprintf_info(session, fp, true); | ||
104 | fclose(fp); | ||
105 | |||
106 | for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++) | ||
107 | argc++; | ||
108 | |||
109 | argv = calloc(argc + 1, sizeof(*argv)); | ||
110 | if (argv == NULL) | ||
111 | goto out; | ||
112 | |||
113 | argv[0] = pos = ptr; | ||
114 | for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) { | ||
115 | *pos++ = '\0'; | ||
116 | argv[i] = pos; | ||
117 | } | ||
118 | |||
119 | BUG_ON(i != argc + 1); | ||
120 | |||
121 | ui__list_menu(argc, argv); | ||
122 | |||
123 | out: | ||
124 | free(argv); | ||
125 | free(ptr); | ||
126 | return 0; | ||
127 | } | ||
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a440e03cd8c2..a7045ea6d1d5 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -1267,10 +1267,8 @@ static inline void free_popup_options(char **options, int n) | |||
1267 | { | 1267 | { |
1268 | int i; | 1268 | int i; |
1269 | 1269 | ||
1270 | for (i = 0; i < n; ++i) { | 1270 | for (i = 0; i < n; ++i) |
1271 | free(options[i]); | 1271 | zfree(&options[i]); |
1272 | options[i] = NULL; | ||
1273 | } | ||
1274 | } | 1272 | } |
1275 | 1273 | ||
1276 | /* Check whether the browser is for 'top' or 'report' */ | 1274 | /* Check whether the browser is for 'top' or 'report' */ |
@@ -1329,7 +1327,7 @@ static int switch_data_file(void) | |||
1329 | 1327 | ||
1330 | abs_path[nr_options] = strdup(path); | 1328 | abs_path[nr_options] = strdup(path); |
1331 | if (!abs_path[nr_options]) { | 1329 | if (!abs_path[nr_options]) { |
1332 | free(options[nr_options]); | 1330 | zfree(&options[nr_options]); |
1333 | ui__warning("Can't search all data files due to memory shortage.\n"); | 1331 | ui__warning("Can't search all data files due to memory shortage.\n"); |
1334 | fclose(file); | 1332 | fclose(file); |
1335 | break; | 1333 | break; |
@@ -1400,6 +1398,36 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
1400 | char script_opt[64]; | 1398 | char script_opt[64]; |
1401 | int delay_secs = hbt ? hbt->refresh : 0; | 1399 | int delay_secs = hbt ? hbt->refresh : 0; |
1402 | 1400 | ||
1401 | #define HIST_BROWSER_HELP_COMMON \ | ||
1402 | "h/?/F1 Show this window\n" \ | ||
1403 | "UP/DOWN/PGUP\n" \ | ||
1404 | "PGDN/SPACE Navigate\n" \ | ||
1405 | "q/ESC/CTRL+C Exit browser\n\n" \ | ||
1406 | "For multiple event sessions:\n\n" \ | ||
1407 | "TAB/UNTAB Switch events\n\n" \ | ||
1408 | "For symbolic views (--sort has sym):\n\n" \ | ||
1409 | "-> Zoom into DSO/Threads & Annotate current symbol\n" \ | ||
1410 | "<- Zoom out\n" \ | ||
1411 | "a Annotate current symbol\n" \ | ||
1412 | "C Collapse all callchains\n" \ | ||
1413 | "d Zoom into current DSO\n" \ | ||
1414 | "E Expand all callchains\n" \ | ||
1415 | |||
1416 | /* help messages are sorted by lexical order of the hotkey */ | ||
1417 | const char report_help[] = HIST_BROWSER_HELP_COMMON | ||
1418 | "i Show header information\n" | ||
1419 | "P Print histograms to perf.hist.N\n" | ||
1420 | "r Run available scripts\n" | ||
1421 | "s Switch to another data file in PWD\n" | ||
1422 | "t Zoom into current Thread\n" | ||
1423 | "V Verbose (DSO names in callchains, etc)\n" | ||
1424 | "/ Filter symbol by name"; | ||
1425 | const char top_help[] = HIST_BROWSER_HELP_COMMON | ||
1426 | "P Print histograms to perf.hist.N\n" | ||
1427 | "t Zoom into current Thread\n" | ||
1428 | "V Verbose (DSO names in callchains, etc)\n" | ||
1429 | "/ Filter symbol by name"; | ||
1430 | |||
1403 | if (browser == NULL) | 1431 | if (browser == NULL) |
1404 | return -1; | 1432 | return -1; |
1405 | 1433 | ||
@@ -1484,29 +1512,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
1484 | if (is_report_browser(hbt)) | 1512 | if (is_report_browser(hbt)) |
1485 | goto do_data_switch; | 1513 | goto do_data_switch; |
1486 | continue; | 1514 | continue; |
1515 | case 'i': | ||
1516 | /* env->arch is NULL for live-mode (i.e. perf top) */ | ||
1517 | if (env->arch) | ||
1518 | tui__header_window(env); | ||
1519 | continue; | ||
1487 | case K_F1: | 1520 | case K_F1: |
1488 | case 'h': | 1521 | case 'h': |
1489 | case '?': | 1522 | case '?': |
1490 | ui_browser__help_window(&browser->b, | 1523 | ui_browser__help_window(&browser->b, |
1491 | "h/?/F1 Show this window\n" | 1524 | is_report_browser(hbt) ? report_help : top_help); |
1492 | "UP/DOWN/PGUP\n" | ||
1493 | "PGDN/SPACE Navigate\n" | ||
1494 | "q/ESC/CTRL+C Exit browser\n\n" | ||
1495 | "For multiple event sessions:\n\n" | ||
1496 | "TAB/UNTAB Switch events\n\n" | ||
1497 | "For symbolic views (--sort has sym):\n\n" | ||
1498 | "-> Zoom into DSO/Threads & Annotate current symbol\n" | ||
1499 | "<- Zoom out\n" | ||
1500 | "a Annotate current symbol\n" | ||
1501 | "C Collapse all callchains\n" | ||
1502 | "E Expand all callchains\n" | ||
1503 | "d Zoom into current DSO\n" | ||
1504 | "t Zoom into current Thread\n" | ||
1505 | "r Run available scripts('perf report' only)\n" | ||
1506 | "s Switch to another data file in PWD ('perf report' only)\n" | ||
1507 | "P Print histograms to perf.hist.N\n" | ||
1508 | "V Verbose (DSO names in callchains, etc)\n" | ||
1509 | "/ Filter symbol by name"); | ||
1510 | continue; | 1525 | continue; |
1511 | case K_ENTER: | 1526 | case K_ENTER: |
1512 | case K_RIGHT: | 1527 | case K_RIGHT: |
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index d63c68ea02a8..402d2bd30b09 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c | |||
@@ -173,8 +173,7 @@ int script_browse(const char *script_opt) | |||
173 | if (script.b.width > AVERAGE_LINE_LEN) | 173 | if (script.b.width > AVERAGE_LINE_LEN) |
174 | script.b.width = AVERAGE_LINE_LEN; | 174 | script.b.width = AVERAGE_LINE_LEN; |
175 | 175 | ||
176 | if (line) | 176 | free(line); |
177 | free(line); | ||
178 | pclose(fp); | 177 | pclose(fp); |
179 | 178 | ||
180 | script.nr_lines = nr_entries; | 179 | script.nr_lines = nr_entries; |
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index 696c1fbe4248..52e7fc48af9f 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c | |||
@@ -23,8 +23,7 @@ int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) | |||
23 | if (!perf_gtk__is_active_context(*ctx)) | 23 | if (!perf_gtk__is_active_context(*ctx)) |
24 | return -1; | 24 | return -1; |
25 | 25 | ||
26 | free(*ctx); | 26 | zfree(ctx); |
27 | *ctx = NULL; | ||
28 | return 0; | 27 | return 0; |
29 | } | 28 | } |
30 | 29 | ||
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index c244cb524ef2..831fbb77d1ff 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -510,7 +510,7 @@ print_entries: | |||
510 | 510 | ||
511 | free(line); | 511 | free(line); |
512 | out: | 512 | out: |
513 | free(rem_sq_bracket); | 513 | zfree(&rem_sq_bracket); |
514 | 514 | ||
515 | return ret; | 515 | return ret; |
516 | } | 516 | } |
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 092902e30cee..bf890f72fe80 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c | |||
@@ -92,6 +92,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
92 | t = sep + 1; | 92 | t = sep + 1; |
93 | } | 93 | } |
94 | 94 | ||
95 | pthread_mutex_lock(&ui__lock); | ||
96 | |||
95 | max_len += 2; | 97 | max_len += 2; |
96 | nr_lines += 8; | 98 | nr_lines += 8; |
97 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; | 99 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; |
@@ -120,13 +122,19 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
120 | SLsmg_write_nstring((char *)exit_msg, max_len); | 122 | SLsmg_write_nstring((char *)exit_msg, max_len); |
121 | SLsmg_refresh(); | 123 | SLsmg_refresh(); |
122 | 124 | ||
125 | pthread_mutex_unlock(&ui__lock); | ||
126 | |||
123 | x += 2; | 127 | x += 2; |
124 | len = 0; | 128 | len = 0; |
125 | key = ui__getch(delay_secs); | 129 | key = ui__getch(delay_secs); |
126 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { | 130 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { |
131 | pthread_mutex_lock(&ui__lock); | ||
132 | |||
127 | if (key == K_BKSPC) { | 133 | if (key == K_BKSPC) { |
128 | if (len == 0) | 134 | if (len == 0) { |
135 | pthread_mutex_unlock(&ui__lock); | ||
129 | goto next_key; | 136 | goto next_key; |
137 | } | ||
130 | SLsmg_gotorc(y, x + --len); | 138 | SLsmg_gotorc(y, x + --len); |
131 | SLsmg_write_char(' '); | 139 | SLsmg_write_char(' '); |
132 | } else { | 140 | } else { |
@@ -136,6 +144,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
136 | } | 144 | } |
137 | SLsmg_refresh(); | 145 | SLsmg_refresh(); |
138 | 146 | ||
147 | pthread_mutex_unlock(&ui__lock); | ||
148 | |||
139 | /* XXX more graceful overflow handling needed */ | 149 | /* XXX more graceful overflow handling needed */ |
140 | if (len == sizeof(buf) - 1) { | 150 | if (len == sizeof(buf) - 1) { |
141 | ui_helpline__push("maximum size of symbol name reached!"); | 151 | ui_helpline__push("maximum size of symbol name reached!"); |
@@ -174,6 +184,8 @@ int ui__question_window(const char *title, const char *text, | |||
174 | t = sep + 1; | 184 | t = sep + 1; |
175 | } | 185 | } |
176 | 186 | ||
187 | pthread_mutex_lock(&ui__lock); | ||
188 | |||
177 | max_len += 2; | 189 | max_len += 2; |
178 | nr_lines += 4; | 190 | nr_lines += 4; |
179 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, | 191 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, |
@@ -195,6 +207,9 @@ int ui__question_window(const char *title, const char *text, | |||
195 | SLsmg_gotorc(y + nr_lines - 1, x); | 207 | SLsmg_gotorc(y + nr_lines - 1, x); |
196 | SLsmg_write_nstring((char *)exit_msg, max_len); | 208 | SLsmg_write_nstring((char *)exit_msg, max_len); |
197 | SLsmg_refresh(); | 209 | SLsmg_refresh(); |
210 | |||
211 | pthread_mutex_unlock(&ui__lock); | ||
212 | |||
198 | return ui__getch(delay_secs); | 213 | return ui__getch(delay_secs); |
199 | } | 214 | } |
200 | 215 | ||
@@ -215,9 +230,7 @@ static int __ui__warning(const char *title, const char *format, va_list args) | |||
215 | if (vasprintf(&s, format, args) > 0) { | 230 | if (vasprintf(&s, format, args) > 0) { |
216 | int key; | 231 | int key; |
217 | 232 | ||
218 | pthread_mutex_lock(&ui__lock); | ||
219 | key = ui__question_window(title, s, "Press any key...", 0); | 233 | key = ui__question_window(title, s, "Press any key...", 0); |
220 | pthread_mutex_unlock(&ui__lock); | ||
221 | free(s); | 234 | free(s); |
222 | return key; | 235 | return key; |
223 | } | 236 | } |
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c index e6d134773d0a..c0b43ee40d95 100644 --- a/tools/perf/util/alias.c +++ b/tools/perf/util/alias.c | |||
@@ -55,8 +55,7 @@ int split_cmdline(char *cmdline, const char ***argv) | |||
55 | src++; | 55 | src++; |
56 | c = cmdline[src]; | 56 | c = cmdline[src]; |
57 | if (!c) { | 57 | if (!c) { |
58 | free(*argv); | 58 | zfree(argv); |
59 | *argv = NULL; | ||
60 | return error("cmdline ends with \\"); | 59 | return error("cmdline ends with \\"); |
61 | } | 60 | } |
62 | } | 61 | } |
@@ -68,8 +67,7 @@ int split_cmdline(char *cmdline, const char ***argv) | |||
68 | cmdline[dst] = 0; | 67 | cmdline[dst] = 0; |
69 | 68 | ||
70 | if (quoted) { | 69 | if (quoted) { |
71 | free(*argv); | 70 | zfree(argv); |
72 | *argv = NULL; | ||
73 | return error("unclosed quote"); | 71 | return error("unclosed quote"); |
74 | } | 72 | } |
75 | 73 | ||
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 0fcd81ea31ae..469eb679fb9d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -26,10 +26,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp); | |||
26 | 26 | ||
27 | static void ins__delete(struct ins_operands *ops) | 27 | static void ins__delete(struct ins_operands *ops) |
28 | { | 28 | { |
29 | free(ops->source.raw); | 29 | zfree(&ops->source.raw); |
30 | free(ops->source.name); | 30 | zfree(&ops->source.name); |
31 | free(ops->target.raw); | 31 | zfree(&ops->target.raw); |
32 | free(ops->target.name); | 32 | zfree(&ops->target.name); |
33 | } | 33 | } |
34 | 34 | ||
35 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, | 35 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, |
@@ -185,8 +185,7 @@ static int lock__parse(struct ins_operands *ops) | |||
185 | return 0; | 185 | return 0; |
186 | 186 | ||
187 | out_free_ops: | 187 | out_free_ops: |
188 | free(ops->locked.ops); | 188 | zfree(&ops->locked.ops); |
189 | ops->locked.ops = NULL; | ||
190 | return 0; | 189 | return 0; |
191 | } | 190 | } |
192 | 191 | ||
@@ -205,9 +204,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, | |||
205 | 204 | ||
206 | static void lock__delete(struct ins_operands *ops) | 205 | static void lock__delete(struct ins_operands *ops) |
207 | { | 206 | { |
208 | free(ops->locked.ops); | 207 | zfree(&ops->locked.ops); |
209 | free(ops->target.raw); | 208 | zfree(&ops->target.raw); |
210 | free(ops->target.name); | 209 | zfree(&ops->target.name); |
211 | } | 210 | } |
212 | 211 | ||
213 | static struct ins_ops lock_ops = { | 212 | static struct ins_ops lock_ops = { |
@@ -256,8 +255,7 @@ static int mov__parse(struct ins_operands *ops) | |||
256 | return 0; | 255 | return 0; |
257 | 256 | ||
258 | out_free_source: | 257 | out_free_source: |
259 | free(ops->source.raw); | 258 | zfree(&ops->source.raw); |
260 | ops->source.raw = NULL; | ||
261 | return -1; | 259 | return -1; |
262 | } | 260 | } |
263 | 261 | ||
@@ -464,17 +462,12 @@ void symbol__annotate_zero_histograms(struct symbol *sym) | |||
464 | pthread_mutex_unlock(¬es->lock); | 462 | pthread_mutex_unlock(¬es->lock); |
465 | } | 463 | } |
466 | 464 | ||
467 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 465 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
468 | int evidx, u64 addr) | 466 | struct annotation *notes, int evidx, u64 addr) |
469 | { | 467 | { |
470 | unsigned offset; | 468 | unsigned offset; |
471 | struct annotation *notes; | ||
472 | struct sym_hist *h; | 469 | struct sym_hist *h; |
473 | 470 | ||
474 | notes = symbol__annotation(sym); | ||
475 | if (notes->src == NULL) | ||
476 | return -ENOMEM; | ||
477 | |||
478 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 471 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
479 | 472 | ||
480 | if (addr < sym->start || addr > sym->end) | 473 | if (addr < sym->start || addr > sym->end) |
@@ -491,6 +484,33 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
491 | return 0; | 484 | return 0; |
492 | } | 485 | } |
493 | 486 | ||
487 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | ||
488 | int evidx, u64 addr) | ||
489 | { | ||
490 | struct annotation *notes; | ||
491 | |||
492 | if (sym == NULL || use_browser != 1 || !sort__has_sym) | ||
493 | return 0; | ||
494 | |||
495 | notes = symbol__annotation(sym); | ||
496 | if (notes->src == NULL) { | ||
497 | if (symbol__alloc_hist(sym) < 0) | ||
498 | return -ENOMEM; | ||
499 | } | ||
500 | |||
501 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); | ||
502 | } | ||
503 | |||
504 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) | ||
505 | { | ||
506 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); | ||
507 | } | ||
508 | |||
509 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | ||
510 | { | ||
511 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | ||
512 | } | ||
513 | |||
494 | static void disasm_line__init_ins(struct disasm_line *dl) | 514 | static void disasm_line__init_ins(struct disasm_line *dl) |
495 | { | 515 | { |
496 | dl->ins = ins__find(dl->name); | 516 | dl->ins = ins__find(dl->name); |
@@ -538,8 +558,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp) | |||
538 | return 0; | 558 | return 0; |
539 | 559 | ||
540 | out_free_name: | 560 | out_free_name: |
541 | free(*namep); | 561 | zfree(namep); |
542 | *namep = NULL; | ||
543 | return -1; | 562 | return -1; |
544 | } | 563 | } |
545 | 564 | ||
@@ -564,7 +583,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs | |||
564 | return dl; | 583 | return dl; |
565 | 584 | ||
566 | out_free_line: | 585 | out_free_line: |
567 | free(dl->line); | 586 | zfree(&dl->line); |
568 | out_delete: | 587 | out_delete: |
569 | free(dl); | 588 | free(dl); |
570 | return NULL; | 589 | return NULL; |
@@ -572,8 +591,8 @@ out_delete: | |||
572 | 591 | ||
573 | void disasm_line__free(struct disasm_line *dl) | 592 | void disasm_line__free(struct disasm_line *dl) |
574 | { | 593 | { |
575 | free(dl->line); | 594 | zfree(&dl->line); |
576 | free(dl->name); | 595 | zfree(&dl->name); |
577 | if (dl->ins && dl->ins->ops->free) | 596 | if (dl->ins && dl->ins->ops->free) |
578 | dl->ins->ops->free(&dl->ops); | 597 | dl->ins->ops->free(&dl->ops); |
579 | else | 598 | else |
@@ -1091,8 +1110,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
1091 | src_line = (void *)src_line + sizeof_src_line; | 1110 | src_line = (void *)src_line + sizeof_src_line; |
1092 | } | 1111 | } |
1093 | 1112 | ||
1094 | free(notes->src->lines); | 1113 | zfree(¬es->src->lines); |
1095 | notes->src->lines = NULL; | ||
1096 | } | 1114 | } |
1097 | 1115 | ||
1098 | /* Get the filename:line for the colored entries */ | 1116 | /* Get the filename:line for the colored entries */ |
@@ -1376,3 +1394,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1376 | 1394 | ||
1377 | return 0; | 1395 | return 0; |
1378 | } | 1396 | } |
1397 | |||
1398 | int hist_entry__annotate(struct hist_entry *he, size_t privsize) | ||
1399 | { | ||
1400 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | ||
1401 | } | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 834b7b57b788..b2aef59d6bb2 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -132,12 +132,17 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) | |||
132 | return &a->annotation; | 132 | return &a->annotation; |
133 | } | 133 | } |
134 | 134 | ||
135 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 135 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); |
136 | int evidx, u64 addr); | 136 | |
137 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); | ||
138 | |||
137 | int symbol__alloc_hist(struct symbol *sym); | 139 | int symbol__alloc_hist(struct symbol *sym); |
138 | void symbol__annotate_zero_histograms(struct symbol *sym); | 140 | void symbol__annotate_zero_histograms(struct symbol *sym); |
139 | 141 | ||
140 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); | 142 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); |
143 | |||
144 | int hist_entry__annotate(struct hist_entry *he, size_t privsize); | ||
145 | |||
141 | int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); | 146 | int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); |
142 | int symbol__annotate_printf(struct symbol *sym, struct map *map, | 147 | int symbol__annotate_printf(struct symbol *sym, struct map *map, |
143 | struct perf_evsel *evsel, bool full_paths, | 148 | struct perf_evsel *evsel, bool full_paths, |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 4f7f989876ec..08b25af9eea1 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -146,7 +146,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor) | |||
146 | 146 | ||
147 | struct option; | 147 | struct option; |
148 | 148 | ||
149 | int record_parse_callchain(const char *arg, struct perf_record_opts *opts); | 149 | int record_parse_callchain(const char *arg, struct record_opts *opts); |
150 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); | 150 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); |
151 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); | 151 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); |
152 | 152 | ||
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 96bbda1ddb83..0922aa4218c2 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c | |||
@@ -133,7 +133,7 @@ void close_cgroup(struct cgroup_sel *cgrp) | |||
133 | /* XXX: not reentrant */ | 133 | /* XXX: not reentrant */ |
134 | if (--cgrp->refcnt == 0) { | 134 | if (--cgrp->refcnt == 0) { |
135 | close(cgrp->fd); | 135 | close(cgrp->fd); |
136 | free(cgrp->name); | 136 | zfree(&cgrp->name); |
137 | free(cgrp); | 137 | free(cgrp); |
138 | } | 138 | } |
139 | } | 139 | } |
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index ee0df0e24cdb..67d1e404c0cb 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -21,7 +21,7 @@ static void comm_str__put(struct comm_str *cs) | |||
21 | { | 21 | { |
22 | if (!--cs->ref) { | 22 | if (!--cs->ref) { |
23 | rb_erase(&cs->rb_node, &comm_str_root); | 23 | rb_erase(&cs->rb_node, &comm_str_root); |
24 | free(cs->str); | 24 | zfree(&cs->str); |
25 | free(cs); | 25 | free(cs); |
26 | } | 26 | } |
27 | } | 27 | } |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 8640a9121e72..299b55586502 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
@@ -25,7 +25,6 @@ static int _eprintf(int level, const char *fmt, va_list args) | |||
25 | ui_helpline__vshow(fmt, args); | 25 | ui_helpline__vshow(fmt, args); |
26 | else | 26 | else |
27 | ret = vfprintf(stderr, fmt, args); | 27 | ret = vfprintf(stderr, fmt, args); |
28 | va_end(args); | ||
29 | } | 28 | } |
30 | 29 | ||
31 | return ret; | 30 | return ret; |
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 4ddeecb9ff85..4045d086d9d9 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -497,21 +497,18 @@ void dso__delete(struct dso *dso) | |||
497 | symbols__delete(&dso->symbols[i]); | 497 | symbols__delete(&dso->symbols[i]); |
498 | 498 | ||
499 | if (dso->short_name_allocated) { | 499 | if (dso->short_name_allocated) { |
500 | free((char *)dso->short_name); | 500 | zfree((char **)&dso->short_name); |
501 | dso->short_name = NULL; | ||
502 | dso->short_name_allocated = false; | 501 | dso->short_name_allocated = false; |
503 | } | 502 | } |
504 | 503 | ||
505 | if (dso->long_name_allocated) { | 504 | if (dso->long_name_allocated) { |
506 | free((char *)dso->long_name); | 505 | zfree((char **)&dso->long_name); |
507 | dso->long_name = NULL; | ||
508 | dso->long_name_allocated = false; | 506 | dso->long_name_allocated = false; |
509 | } | 507 | } |
510 | 508 | ||
511 | dso_cache__free(&dso->cache); | 509 | dso_cache__free(&dso->cache); |
512 | dso__free_a2l(dso); | 510 | dso__free_a2l(dso); |
513 | free(dso->symsrc_filename); | 511 | zfree(&dso->symsrc_filename); |
514 | dso->symsrc_filename = NULL; | ||
515 | free(dso); | 512 | free(dso); |
516 | } | 513 | } |
517 | 514 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 694876877ae2..45a76c69a9ed 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -106,8 +106,12 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
106 | 106 | ||
107 | memset(&event->comm, 0, sizeof(event->comm)); | 107 | memset(&event->comm, 0, sizeof(event->comm)); |
108 | 108 | ||
109 | tgid = perf_event__get_comm_tgid(pid, event->comm.comm, | 109 | if (machine__is_host(machine)) |
110 | sizeof(event->comm.comm)); | 110 | tgid = perf_event__get_comm_tgid(pid, event->comm.comm, |
111 | sizeof(event->comm.comm)); | ||
112 | else | ||
113 | tgid = machine->pid; | ||
114 | |||
111 | if (tgid < 0) | 115 | if (tgid < 0) |
112 | goto out; | 116 | goto out; |
113 | 117 | ||
@@ -129,7 +133,11 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
129 | goto out; | 133 | goto out; |
130 | } | 134 | } |
131 | 135 | ||
132 | snprintf(filename, sizeof(filename), "/proc/%d/task", pid); | 136 | if (machine__is_default_guest(machine)) |
137 | return 0; | ||
138 | |||
139 | snprintf(filename, sizeof(filename), "%s/proc/%d/task", | ||
140 | machine->root_dir, pid); | ||
133 | 141 | ||
134 | tasks = opendir(filename); | 142 | tasks = opendir(filename); |
135 | if (tasks == NULL) { | 143 | if (tasks == NULL) { |
@@ -178,7 +186,11 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
178 | FILE *fp; | 186 | FILE *fp; |
179 | int rc = 0; | 187 | int rc = 0; |
180 | 188 | ||
181 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); | 189 | if (machine__is_default_guest(machine)) |
190 | return 0; | ||
191 | |||
192 | snprintf(filename, sizeof(filename), "%s/proc/%d/maps", | ||
193 | machine->root_dir, pid); | ||
182 | 194 | ||
183 | fp = fopen(filename, "r"); | 195 | fp = fopen(filename, "r"); |
184 | if (fp == NULL) { | 196 | if (fp == NULL) { |
@@ -218,7 +230,10 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
218 | /* | 230 | /* |
219 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | 231 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c |
220 | */ | 232 | */ |
221 | event->header.misc = PERF_RECORD_MISC_USER; | 233 | if (machine__is_host(machine)) |
234 | event->header.misc = PERF_RECORD_MISC_USER; | ||
235 | else | ||
236 | event->header.misc = PERF_RECORD_MISC_GUEST_USER; | ||
222 | 237 | ||
223 | if (prot[2] != 'x') { | 238 | if (prot[2] != 'x') { |
224 | if (!mmap_data || prot[0] != 'r') | 239 | if (!mmap_data || prot[0] != 'r') |
@@ -387,6 +402,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
387 | struct machine *machine, bool mmap_data) | 402 | struct machine *machine, bool mmap_data) |
388 | { | 403 | { |
389 | DIR *proc; | 404 | DIR *proc; |
405 | char proc_path[PATH_MAX]; | ||
390 | struct dirent dirent, *next; | 406 | struct dirent dirent, *next; |
391 | union perf_event *comm_event, *mmap_event; | 407 | union perf_event *comm_event, *mmap_event; |
392 | int err = -1; | 408 | int err = -1; |
@@ -399,7 +415,12 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
399 | if (mmap_event == NULL) | 415 | if (mmap_event == NULL) |
400 | goto out_free_comm; | 416 | goto out_free_comm; |
401 | 417 | ||
402 | proc = opendir("/proc"); | 418 | if (machine__is_default_guest(machine)) |
419 | return 0; | ||
420 | |||
421 | snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); | ||
422 | proc = opendir(proc_path); | ||
423 | |||
403 | if (proc == NULL) | 424 | if (proc == NULL) |
404 | goto out_free_mmap; | 425 | goto out_free_mmap; |
405 | 426 | ||
@@ -638,6 +659,7 @@ void thread__find_addr_map(struct thread *thread, | |||
638 | struct map_groups *mg = &thread->mg; | 659 | struct map_groups *mg = &thread->mg; |
639 | bool load_map = false; | 660 | bool load_map = false; |
640 | 661 | ||
662 | al->machine = machine; | ||
641 | al->thread = thread; | 663 | al->thread = thread; |
642 | al->addr = addr; | 664 | al->addr = addr; |
643 | al->cpumode = cpumode; | 665 | al->cpumode = cpumode; |
@@ -658,15 +680,10 @@ void thread__find_addr_map(struct thread *thread, | |||
658 | al->level = 'g'; | 680 | al->level = 'g'; |
659 | mg = &machine->kmaps; | 681 | mg = &machine->kmaps; |
660 | load_map = true; | 682 | load_map = true; |
683 | } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { | ||
684 | al->level = 'u'; | ||
661 | } else { | 685 | } else { |
662 | /* | 686 | al->level = 'H'; |
663 | * 'u' means guest os user space. | ||
664 | * TODO: We don't support guest user space. Might support late. | ||
665 | */ | ||
666 | if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) | ||
667 | al->level = 'u'; | ||
668 | else | ||
669 | al->level = 'H'; | ||
670 | al->map = NULL; | 687 | al->map = NULL; |
671 | 688 | ||
672 | if ((cpumode == PERF_RECORD_MISC_GUEST_USER || | 689 | if ((cpumode == PERF_RECORD_MISC_GUEST_USER || |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index da3182914984..b08a7ecdcea1 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -101,10 +101,8 @@ static void perf_evlist__purge(struct perf_evlist *evlist) | |||
101 | 101 | ||
102 | void perf_evlist__exit(struct perf_evlist *evlist) | 102 | void perf_evlist__exit(struct perf_evlist *evlist) |
103 | { | 103 | { |
104 | free(evlist->mmap); | 104 | zfree(&evlist->mmap); |
105 | free(evlist->pollfd); | 105 | zfree(&evlist->pollfd); |
106 | evlist->mmap = NULL; | ||
107 | evlist->pollfd = NULL; | ||
108 | } | 106 | } |
109 | 107 | ||
110 | void perf_evlist__delete(struct perf_evlist *evlist) | 108 | void perf_evlist__delete(struct perf_evlist *evlist) |
@@ -587,8 +585,7 @@ void perf_evlist__munmap(struct perf_evlist *evlist) | |||
587 | for (i = 0; i < evlist->nr_mmaps; i++) | 585 | for (i = 0; i < evlist->nr_mmaps; i++) |
588 | __perf_evlist__munmap(evlist, i); | 586 | __perf_evlist__munmap(evlist, i); |
589 | 587 | ||
590 | free(evlist->mmap); | 588 | zfree(&evlist->mmap); |
591 | evlist->mmap = NULL; | ||
592 | } | 589 | } |
593 | 590 | ||
594 | static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) | 591 | static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 9f64ede3ecbd..2fe51958ed85 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -12,7 +12,7 @@ | |||
12 | struct pollfd; | 12 | struct pollfd; |
13 | struct thread_map; | 13 | struct thread_map; |
14 | struct cpu_map; | 14 | struct cpu_map; |
15 | struct perf_record_opts; | 15 | struct record_opts; |
16 | 16 | ||
17 | #define PERF_EVLIST__HLIST_BITS 8 | 17 | #define PERF_EVLIST__HLIST_BITS 8 |
18 | #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) | 18 | #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) |
@@ -97,9 +97,8 @@ void perf_evlist__close(struct perf_evlist *evlist); | |||
97 | 97 | ||
98 | void perf_evlist__set_id_pos(struct perf_evlist *evlist); | 98 | void perf_evlist__set_id_pos(struct perf_evlist *evlist); |
99 | bool perf_can_sample_identifier(void); | 99 | bool perf_can_sample_identifier(void); |
100 | void perf_evlist__config(struct perf_evlist *evlist, | 100 | void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts); |
101 | struct perf_record_opts *opts); | 101 | int record_opts__config(struct record_opts *opts); |
102 | int perf_record_opts__config(struct perf_record_opts *opts); | ||
103 | 102 | ||
104 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, | 103 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, |
105 | struct target *target, | 104 | struct target *target, |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 01ff4cfde1f5..ade8d9c1c431 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -208,7 +208,7 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int | |||
208 | return evsel; | 208 | return evsel; |
209 | 209 | ||
210 | out_free: | 210 | out_free: |
211 | free(evsel->name); | 211 | zfree(&evsel->name); |
212 | free(evsel); | 212 | free(evsel); |
213 | return NULL; | 213 | return NULL; |
214 | } | 214 | } |
@@ -528,8 +528,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) | |||
528 | * enable/disable events specifically, as there's no | 528 | * enable/disable events specifically, as there's no |
529 | * initial traced exec call. | 529 | * initial traced exec call. |
530 | */ | 530 | */ |
531 | void perf_evsel__config(struct perf_evsel *evsel, | 531 | void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) |
532 | struct perf_record_opts *opts) | ||
533 | { | 532 | { |
534 | struct perf_evsel *leader = evsel->leader; | 533 | struct perf_evsel *leader = evsel->leader; |
535 | struct perf_event_attr *attr = &evsel->attr; | 534 | struct perf_event_attr *attr = &evsel->attr; |
@@ -751,8 +750,7 @@ void perf_evsel__free_id(struct perf_evsel *evsel) | |||
751 | { | 750 | { |
752 | xyarray__delete(evsel->sample_id); | 751 | xyarray__delete(evsel->sample_id); |
753 | evsel->sample_id = NULL; | 752 | evsel->sample_id = NULL; |
754 | free(evsel->id); | 753 | zfree(&evsel->id); |
755 | evsel->id = NULL; | ||
756 | } | 754 | } |
757 | 755 | ||
758 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 756 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
@@ -768,7 +766,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | |||
768 | 766 | ||
769 | void perf_evsel__free_counts(struct perf_evsel *evsel) | 767 | void perf_evsel__free_counts(struct perf_evsel *evsel) |
770 | { | 768 | { |
771 | free(evsel->counts); | 769 | zfree(&evsel->counts); |
772 | } | 770 | } |
773 | 771 | ||
774 | void perf_evsel__exit(struct perf_evsel *evsel) | 772 | void perf_evsel__exit(struct perf_evsel *evsel) |
@@ -782,10 +780,10 @@ void perf_evsel__delete(struct perf_evsel *evsel) | |||
782 | { | 780 | { |
783 | perf_evsel__exit(evsel); | 781 | perf_evsel__exit(evsel); |
784 | close_cgroup(evsel->cgrp); | 782 | close_cgroup(evsel->cgrp); |
785 | free(evsel->group_name); | 783 | zfree(&evsel->group_name); |
786 | if (evsel->tp_format) | 784 | if (evsel->tp_format) |
787 | pevent_free_format(evsel->tp_format); | 785 | pevent_free_format(evsel->tp_format); |
788 | free(evsel->name); | 786 | zfree(&evsel->name); |
789 | free(evsel); | 787 | free(evsel); |
790 | } | 788 | } |
791 | 789 | ||
@@ -1961,8 +1959,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | |||
1961 | evsel->attr.type = PERF_TYPE_SOFTWARE; | 1959 | evsel->attr.type = PERF_TYPE_SOFTWARE; |
1962 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; | 1960 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; |
1963 | 1961 | ||
1964 | free(evsel->name); | 1962 | zfree(&evsel->name); |
1965 | evsel->name = NULL; | ||
1966 | return true; | 1963 | return true; |
1967 | } | 1964 | } |
1968 | 1965 | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8120eeb86ac1..f1b325665aae 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -96,7 +96,7 @@ struct perf_evsel { | |||
96 | struct cpu_map; | 96 | struct cpu_map; |
97 | struct thread_map; | 97 | struct thread_map; |
98 | struct perf_evlist; | 98 | struct perf_evlist; |
99 | struct perf_record_opts; | 99 | struct record_opts; |
100 | 100 | ||
101 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); | 101 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); |
102 | 102 | ||
@@ -120,7 +120,7 @@ void perf_evsel__exit(struct perf_evsel *evsel); | |||
120 | void perf_evsel__delete(struct perf_evsel *evsel); | 120 | void perf_evsel__delete(struct perf_evsel *evsel); |
121 | 121 | ||
122 | void perf_evsel__config(struct perf_evsel *evsel, | 122 | void perf_evsel__config(struct perf_evsel *evsel, |
123 | struct perf_record_opts *opts); | 123 | struct record_opts *opts); |
124 | 124 | ||
125 | int __perf_evsel__sample_size(u64 sample_type); | 125 | int __perf_evsel__sample_size(u64 sample_type); |
126 | void perf_evsel__calc_id_pos(struct perf_evsel *evsel); | 126 | void perf_evsel__calc_id_pos(struct perf_evsel *evsel); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 61c54213704b..a4a60b7887ee 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -800,10 +800,10 @@ static void free_cpu_topo(struct cpu_topo *tp) | |||
800 | return; | 800 | return; |
801 | 801 | ||
802 | for (i = 0 ; i < tp->core_sib; i++) | 802 | for (i = 0 ; i < tp->core_sib; i++) |
803 | free(tp->core_siblings[i]); | 803 | zfree(&tp->core_siblings[i]); |
804 | 804 | ||
805 | for (i = 0 ; i < tp->thread_sib; i++) | 805 | for (i = 0 ; i < tp->thread_sib; i++) |
806 | free(tp->thread_siblings[i]); | 806 | zfree(&tp->thread_siblings[i]); |
807 | 807 | ||
808 | free(tp); | 808 | free(tp); |
809 | } | 809 | } |
@@ -1232,10 +1232,8 @@ static void free_event_desc(struct perf_evsel *events) | |||
1232 | return; | 1232 | return; |
1233 | 1233 | ||
1234 | for (evsel = events; evsel->attr.size; evsel++) { | 1234 | for (evsel = events; evsel->attr.size; evsel++) { |
1235 | if (evsel->name) | 1235 | zfree(&evsel->name); |
1236 | free(evsel->name); | 1236 | zfree(&evsel->id); |
1237 | if (evsel->id) | ||
1238 | free(evsel->id); | ||
1239 | } | 1237 | } |
1240 | 1238 | ||
1241 | free(events); | 1239 | free(events); |
@@ -1326,8 +1324,7 @@ read_event_desc(struct perf_header *ph, int fd) | |||
1326 | } | 1324 | } |
1327 | } | 1325 | } |
1328 | out: | 1326 | out: |
1329 | if (buf) | 1327 | free(buf); |
1330 | free(buf); | ||
1331 | return events; | 1328 | return events; |
1332 | error: | 1329 | error: |
1333 | if (events) | 1330 | if (events) |
@@ -2108,7 +2105,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, | |||
2108 | ret = 0; | 2105 | ret = 0; |
2109 | out_free: | 2106 | out_free: |
2110 | for (i = 0; i < nr_groups; i++) | 2107 | for (i = 0; i < nr_groups; i++) |
2111 | free(desc[i].name); | 2108 | zfree(&desc[i].name); |
2112 | free(desc); | 2109 | free(desc); |
2113 | 2110 | ||
2114 | return ret; | 2111 | return ret; |
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 8b1f6e891b8a..86c37c472263 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c | |||
@@ -22,8 +22,8 @@ static void clean_cmdnames(struct cmdnames *cmds) | |||
22 | unsigned int i; | 22 | unsigned int i; |
23 | 23 | ||
24 | for (i = 0; i < cmds->cnt; ++i) | 24 | for (i = 0; i < cmds->cnt; ++i) |
25 | free(cmds->names[i]); | 25 | zfree(&cmds->names[i]); |
26 | free(cmds->names); | 26 | zfree(&cmds->names); |
27 | cmds->cnt = 0; | 27 | cmds->cnt = 0; |
28 | cmds->alloc = 0; | 28 | cmds->alloc = 0; |
29 | } | 29 | } |
@@ -263,9 +263,8 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | |||
263 | 263 | ||
264 | for (i = 0; i < old->cnt; i++) | 264 | for (i = 0; i < old->cnt; i++) |
265 | cmds->names[cmds->cnt++] = old->names[i]; | 265 | cmds->names[cmds->cnt++] = old->names[i]; |
266 | free(old->names); | 266 | zfree(&old->names); |
267 | old->cnt = 0; | 267 | old->cnt = 0; |
268 | old->names = NULL; | ||
269 | } | 268 | } |
270 | 269 | ||
271 | const char *help_unknown_cmd(const char *cmd) | 270 | const char *help_unknown_cmd(const char *cmd) |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 822903eaa201..4ed3e883240d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #include "annotate.h" | ||
2 | #include "util.h" | 1 | #include "util.h" |
3 | #include "build-id.h" | 2 | #include "build-id.h" |
4 | #include "hist.h" | 3 | #include "hist.h" |
@@ -342,15 +341,15 @@ static u8 symbol__parent_filter(const struct symbol *parent) | |||
342 | } | 341 | } |
343 | 342 | ||
344 | static struct hist_entry *add_hist_entry(struct hists *hists, | 343 | static struct hist_entry *add_hist_entry(struct hists *hists, |
345 | struct hist_entry *entry, | 344 | struct hist_entry *entry, |
346 | struct addr_location *al, | 345 | struct addr_location *al) |
347 | u64 period, | ||
348 | u64 weight) | ||
349 | { | 346 | { |
350 | struct rb_node **p; | 347 | struct rb_node **p; |
351 | struct rb_node *parent = NULL; | 348 | struct rb_node *parent = NULL; |
352 | struct hist_entry *he; | 349 | struct hist_entry *he; |
353 | int64_t cmp; | 350 | int64_t cmp; |
351 | u64 period = entry->stat.period; | ||
352 | u64 weight = entry->stat.weight; | ||
354 | 353 | ||
355 | p = &hists->entries_in->rb_node; | 354 | p = &hists->entries_in->rb_node; |
356 | 355 | ||
@@ -373,7 +372,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
373 | * This mem info was allocated from machine__resolve_mem | 372 | * This mem info was allocated from machine__resolve_mem |
374 | * and will not be used anymore. | 373 | * and will not be used anymore. |
375 | */ | 374 | */ |
376 | free(entry->mem_info); | 375 | zfree(&entry->mem_info); |
377 | 376 | ||
378 | /* If the map of an existing hist_entry has | 377 | /* If the map of an existing hist_entry has |
379 | * become out-of-date due to an exec() or | 378 | * become out-of-date due to an exec() or |
@@ -437,7 +436,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists, | |||
437 | .transaction = transaction, | 436 | .transaction = transaction, |
438 | }; | 437 | }; |
439 | 438 | ||
440 | return add_hist_entry(hists, &entry, al, period, weight); | 439 | return add_hist_entry(hists, &entry, al); |
441 | } | 440 | } |
442 | 441 | ||
443 | int64_t | 442 | int64_t |
@@ -476,8 +475,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) | |||
476 | 475 | ||
477 | void hist_entry__free(struct hist_entry *he) | 476 | void hist_entry__free(struct hist_entry *he) |
478 | { | 477 | { |
479 | free(he->branch_info); | 478 | zfree(&he->branch_info); |
480 | free(he->mem_info); | 479 | zfree(&he->mem_info); |
481 | free_srcline(he->srcline); | 480 | free_srcline(he->srcline); |
482 | free(he); | 481 | free(he); |
483 | } | 482 | } |
@@ -807,16 +806,6 @@ void hists__filter_by_symbol(struct hists *hists) | |||
807 | } | 806 | } |
808 | } | 807 | } |
809 | 808 | ||
810 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | ||
811 | { | ||
812 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | ||
813 | } | ||
814 | |||
815 | int hist_entry__annotate(struct hist_entry *he, size_t privsize) | ||
816 | { | ||
817 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | ||
818 | } | ||
819 | |||
820 | void events_stats__inc(struct events_stats *stats, u32 type) | 809 | void events_stats__inc(struct events_stats *stats, u32 type) |
821 | { | 810 | { |
822 | ++stats->nr_events[0]; | 811 | ++stats->nr_events[0]; |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index b621347a1585..a59743fa3ef7 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -111,9 +111,6 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); | |||
111 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | 111 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, |
112 | int max_cols, float min_pcnt, FILE *fp); | 112 | int max_cols, float min_pcnt, FILE *fp); |
113 | 113 | ||
114 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); | ||
115 | int hist_entry__annotate(struct hist_entry *he, size_t privsize); | ||
116 | |||
117 | void hists__filter_by_dso(struct hists *hists); | 114 | void hists__filter_by_dso(struct hists *hists); |
118 | void hists__filter_by_thread(struct hists *hists); | 115 | void hists__filter_by_thread(struct hists *hists); |
119 | void hists__filter_by_symbol(struct hists *hists); | 116 | void hists__filter_by_symbol(struct hists *hists); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index c78cc84f433e..a98538dc465a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -102,8 +102,7 @@ void machine__exit(struct machine *machine) | |||
102 | map_groups__exit(&machine->kmaps); | 102 | map_groups__exit(&machine->kmaps); |
103 | dsos__delete(&machine->user_dsos); | 103 | dsos__delete(&machine->user_dsos); |
104 | dsos__delete(&machine->kernel_dsos); | 104 | dsos__delete(&machine->kernel_dsos); |
105 | free(machine->root_dir); | 105 | zfree(&machine->root_dir); |
106 | machine->root_dir = NULL; | ||
107 | } | 106 | } |
108 | 107 | ||
109 | void machine__delete(struct machine *machine) | 108 | void machine__delete(struct machine *machine) |
@@ -562,11 +561,10 @@ void machine__destroy_kernel_maps(struct machine *machine) | |||
562 | * on one of them. | 561 | * on one of them. |
563 | */ | 562 | */ |
564 | if (type == MAP__FUNCTION) { | 563 | if (type == MAP__FUNCTION) { |
565 | free((char *)kmap->ref_reloc_sym->name); | 564 | zfree((char **)&kmap->ref_reloc_sym->name); |
566 | kmap->ref_reloc_sym->name = NULL; | 565 | zfree(&kmap->ref_reloc_sym); |
567 | free(kmap->ref_reloc_sym); | 566 | } else |
568 | } | 567 | kmap->ref_reloc_sym = NULL; |
569 | kmap->ref_reloc_sym = NULL; | ||
570 | } | 568 | } |
571 | 569 | ||
572 | map__delete(machine->vmlinux_maps[type]); | 570 | map__delete(machine->vmlinux_maps[type]); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 094c28ba2fae..0153435b8427 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -204,7 +204,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) | |||
204 | } | 204 | } |
205 | path->name = malloc(MAX_EVENT_LENGTH); | 205 | path->name = malloc(MAX_EVENT_LENGTH); |
206 | if (!path->name) { | 206 | if (!path->name) { |
207 | free(path->system); | 207 | zfree(&path->system); |
208 | free(path); | 208 | free(path); |
209 | return NULL; | 209 | return NULL; |
210 | } | 210 | } |
@@ -236,8 +236,8 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name) | |||
236 | path->name = strdup(str+1); | 236 | path->name = strdup(str+1); |
237 | 237 | ||
238 | if (path->system == NULL || path->name == NULL) { | 238 | if (path->system == NULL || path->name == NULL) { |
239 | free(path->system); | 239 | zfree(&path->system); |
240 | free(path->name); | 240 | zfree(&path->name); |
241 | free(path); | 241 | free(path); |
242 | path = NULL; | 242 | path = NULL; |
243 | } | 243 | } |
@@ -917,7 +917,7 @@ int parse_events_terms(struct list_head *terms, const char *str) | |||
917 | ret = parse_events__scanner(str, &data, PE_START_TERMS); | 917 | ret = parse_events__scanner(str, &data, PE_START_TERMS); |
918 | if (!ret) { | 918 | if (!ret) { |
919 | list_splice(data.terms, terms); | 919 | list_splice(data.terms, terms); |
920 | free(data.terms); | 920 | zfree(&data.terms); |
921 | return 0; | 921 | return 0; |
922 | } | 922 | } |
923 | 923 | ||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 56fc10a5e288..0934d645ebdc 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -755,7 +755,7 @@ void print_pmu_events(const char *event_glob, bool name_only) | |||
755 | continue; | 755 | continue; |
756 | } | 756 | } |
757 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); | 757 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); |
758 | free(aliases[j]); | 758 | zfree(&aliases[j]); |
759 | printed++; | 759 | printed++; |
760 | } | 760 | } |
761 | if (printed) | 761 | if (printed) |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 544ac1898a9f..86ed8580c3cb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -172,6 +172,52 @@ const char *kernel_get_module_path(const char *module) | |||
172 | return (dso) ? dso->long_name : NULL; | 172 | return (dso) ? dso->long_name : NULL; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* Copied from unwind.c */ | ||
176 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
177 | GElf_Shdr *shp, const char *name) | ||
178 | { | ||
179 | Elf_Scn *sec = NULL; | ||
180 | |||
181 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
182 | char *str; | ||
183 | |||
184 | gelf_getshdr(sec, shp); | ||
185 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
186 | if (!strcmp(name, str)) | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | return sec; | ||
191 | } | ||
192 | |||
193 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
194 | { | ||
195 | Elf *elf; | ||
196 | GElf_Ehdr ehdr; | ||
197 | GElf_Shdr shdr; | ||
198 | int fd, ret = -ENOENT; | ||
199 | |||
200 | fd = open(exec, O_RDONLY); | ||
201 | if (fd < 0) | ||
202 | return -errno; | ||
203 | |||
204 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
205 | if (elf == NULL) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
209 | goto out; | ||
210 | |||
211 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text")) | ||
212 | goto out; | ||
213 | |||
214 | *address = shdr.sh_addr - shdr.sh_offset; | ||
215 | ret = 0; | ||
216 | out: | ||
217 | elf_end(elf); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
175 | static int init_user_exec(void) | 221 | static int init_user_exec(void) |
176 | { | 222 | { |
177 | int ret = 0; | 223 | int ret = 0; |
@@ -186,6 +232,37 @@ static int init_user_exec(void) | |||
186 | return ret; | 232 | return ret; |
187 | } | 233 | } |
188 | 234 | ||
235 | static int convert_exec_to_group(const char *exec, char **result) | ||
236 | { | ||
237 | char *ptr1, *ptr2, *exec_copy; | ||
238 | char buf[64]; | ||
239 | int ret; | ||
240 | |||
241 | exec_copy = strdup(exec); | ||
242 | if (!exec_copy) | ||
243 | return -ENOMEM; | ||
244 | |||
245 | ptr1 = basename(exec_copy); | ||
246 | if (!ptr1) { | ||
247 | ret = -EINVAL; | ||
248 | goto out; | ||
249 | } | ||
250 | |||
251 | ptr2 = strpbrk(ptr1, "-._"); | ||
252 | if (ptr2) | ||
253 | *ptr2 = '\0'; | ||
254 | ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1); | ||
255 | if (ret < 0) | ||
256 | goto out; | ||
257 | |||
258 | *result = strdup(buf); | ||
259 | ret = *result ? 0 : -ENOMEM; | ||
260 | |||
261 | out: | ||
262 | free(exec_copy); | ||
263 | return ret; | ||
264 | } | ||
265 | |||
189 | static int convert_to_perf_probe_point(struct probe_trace_point *tp, | 266 | static int convert_to_perf_probe_point(struct probe_trace_point *tp, |
190 | struct perf_probe_point *pp) | 267 | struct perf_probe_point *pp) |
191 | { | 268 | { |
@@ -261,6 +338,40 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | |||
261 | return 0; | 338 | return 0; |
262 | } | 339 | } |
263 | 340 | ||
341 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | ||
342 | int ntevs, const char *exec) | ||
343 | { | ||
344 | int i, ret = 0; | ||
345 | unsigned long offset, stext = 0; | ||
346 | char buf[32]; | ||
347 | |||
348 | if (!exec) | ||
349 | return 0; | ||
350 | |||
351 | ret = get_text_start_address(exec, &stext); | ||
352 | if (ret < 0) | ||
353 | return ret; | ||
354 | |||
355 | for (i = 0; i < ntevs && ret >= 0; i++) { | ||
356 | offset = tevs[i].point.address - stext; | ||
357 | offset += tevs[i].point.offset; | ||
358 | tevs[i].point.offset = 0; | ||
359 | zfree(&tevs[i].point.symbol); | ||
360 | ret = e_snprintf(buf, 32, "0x%lx", offset); | ||
361 | if (ret < 0) | ||
362 | break; | ||
363 | tevs[i].point.module = strdup(exec); | ||
364 | tevs[i].point.symbol = strdup(buf); | ||
365 | if (!tevs[i].point.symbol || !tevs[i].point.module) { | ||
366 | ret = -ENOMEM; | ||
367 | break; | ||
368 | } | ||
369 | tevs[i].uprobes = true; | ||
370 | } | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
264 | static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, | 375 | static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, |
265 | int ntevs, const char *module) | 376 | int ntevs, const char *module) |
266 | { | 377 | { |
@@ -290,9 +401,7 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, | |||
290 | } | 401 | } |
291 | } | 402 | } |
292 | 403 | ||
293 | if (tmp) | 404 | free(tmp); |
294 | free(tmp); | ||
295 | |||
296 | return ret; | 405 | return ret; |
297 | } | 406 | } |
298 | 407 | ||
@@ -305,15 +414,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
305 | struct debuginfo *dinfo; | 414 | struct debuginfo *dinfo; |
306 | int ntevs, ret = 0; | 415 | int ntevs, ret = 0; |
307 | 416 | ||
308 | if (pev->uprobes) { | ||
309 | if (need_dwarf) { | ||
310 | pr_warning("Debuginfo-analysis is not yet supported" | ||
311 | " with -x/--exec option.\n"); | ||
312 | return -ENOSYS; | ||
313 | } | ||
314 | return convert_name_to_addr(pev, target); | ||
315 | } | ||
316 | |||
317 | dinfo = open_debuginfo(target); | 417 | dinfo = open_debuginfo(target); |
318 | 418 | ||
319 | if (!dinfo) { | 419 | if (!dinfo) { |
@@ -332,9 +432,14 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
332 | 432 | ||
333 | if (ntevs > 0) { /* Succeeded to find trace events */ | 433 | if (ntevs > 0) { /* Succeeded to find trace events */ |
334 | pr_debug("find %d probe_trace_events.\n", ntevs); | 434 | pr_debug("find %d probe_trace_events.\n", ntevs); |
335 | if (target) | 435 | if (target) { |
336 | ret = add_module_to_probe_trace_events(*tevs, ntevs, | 436 | if (pev->uprobes) |
337 | target); | 437 | ret = add_exec_to_probe_trace_events(*tevs, |
438 | ntevs, target); | ||
439 | else | ||
440 | ret = add_module_to_probe_trace_events(*tevs, | ||
441 | ntevs, target); | ||
442 | } | ||
338 | return ret < 0 ? ret : ntevs; | 443 | return ret < 0 ? ret : ntevs; |
339 | } | 444 | } |
340 | 445 | ||
@@ -401,15 +506,13 @@ static int get_real_path(const char *raw_path, const char *comp_dir, | |||
401 | case EFAULT: | 506 | case EFAULT: |
402 | raw_path = strchr(++raw_path, '/'); | 507 | raw_path = strchr(++raw_path, '/'); |
403 | if (!raw_path) { | 508 | if (!raw_path) { |
404 | free(*new_path); | 509 | zfree(new_path); |
405 | *new_path = NULL; | ||
406 | return -ENOENT; | 510 | return -ENOENT; |
407 | } | 511 | } |
408 | continue; | 512 | continue; |
409 | 513 | ||
410 | default: | 514 | default: |
411 | free(*new_path); | 515 | zfree(new_path); |
412 | *new_path = NULL; | ||
413 | return -errno; | 516 | return -errno; |
414 | } | 517 | } |
415 | } | 518 | } |
@@ -580,7 +683,7 @@ static int show_available_vars_at(struct debuginfo *dinfo, | |||
580 | */ | 683 | */ |
581 | fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, | 684 | fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, |
582 | vl->point.offset); | 685 | vl->point.offset); |
583 | free(vl->point.symbol); | 686 | zfree(&vl->point.symbol); |
584 | nvars = 0; | 687 | nvars = 0; |
585 | if (vl->vars) { | 688 | if (vl->vars) { |
586 | strlist__for_each(node, vl->vars) { | 689 | strlist__for_each(node, vl->vars) { |
@@ -654,9 +757,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
654 | return -ENOSYS; | 757 | return -ENOSYS; |
655 | } | 758 | } |
656 | 759 | ||
657 | if (pev->uprobes) | ||
658 | return convert_name_to_addr(pev, target); | ||
659 | |||
660 | return 0; | 760 | return 0; |
661 | } | 761 | } |
662 | 762 | ||
@@ -1278,8 +1378,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) | |||
1278 | error: | 1378 | error: |
1279 | pr_debug("Failed to synthesize perf probe point: %s\n", | 1379 | pr_debug("Failed to synthesize perf probe point: %s\n", |
1280 | strerror(-ret)); | 1380 | strerror(-ret)); |
1281 | if (buf) | 1381 | free(buf); |
1282 | free(buf); | ||
1283 | return NULL; | 1382 | return NULL; |
1284 | } | 1383 | } |
1285 | 1384 | ||
@@ -1480,34 +1579,25 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
1480 | struct perf_probe_arg_field *field, *next; | 1579 | struct perf_probe_arg_field *field, *next; |
1481 | int i; | 1580 | int i; |
1482 | 1581 | ||
1483 | if (pev->event) | 1582 | free(pev->event); |
1484 | free(pev->event); | 1583 | free(pev->group); |
1485 | if (pev->group) | 1584 | free(pp->file); |
1486 | free(pev->group); | 1585 | free(pp->function); |
1487 | if (pp->file) | 1586 | free(pp->lazy_line); |
1488 | free(pp->file); | 1587 | |
1489 | if (pp->function) | ||
1490 | free(pp->function); | ||
1491 | if (pp->lazy_line) | ||
1492 | free(pp->lazy_line); | ||
1493 | for (i = 0; i < pev->nargs; i++) { | 1588 | for (i = 0; i < pev->nargs; i++) { |
1494 | if (pev->args[i].name) | 1589 | free(pev->args[i].name); |
1495 | free(pev->args[i].name); | 1590 | free(pev->args[i].var); |
1496 | if (pev->args[i].var) | 1591 | free(pev->args[i].type); |
1497 | free(pev->args[i].var); | ||
1498 | if (pev->args[i].type) | ||
1499 | free(pev->args[i].type); | ||
1500 | field = pev->args[i].field; | 1592 | field = pev->args[i].field; |
1501 | while (field) { | 1593 | while (field) { |
1502 | next = field->next; | 1594 | next = field->next; |
1503 | if (field->name) | 1595 | zfree(&field->name); |
1504 | free(field->name); | ||
1505 | free(field); | 1596 | free(field); |
1506 | field = next; | 1597 | field = next; |
1507 | } | 1598 | } |
1508 | } | 1599 | } |
1509 | if (pev->args) | 1600 | free(pev->args); |
1510 | free(pev->args); | ||
1511 | memset(pev, 0, sizeof(*pev)); | 1601 | memset(pev, 0, sizeof(*pev)); |
1512 | } | 1602 | } |
1513 | 1603 | ||
@@ -1516,21 +1606,14 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) | |||
1516 | struct probe_trace_arg_ref *ref, *next; | 1606 | struct probe_trace_arg_ref *ref, *next; |
1517 | int i; | 1607 | int i; |
1518 | 1608 | ||
1519 | if (tev->event) | 1609 | free(tev->event); |
1520 | free(tev->event); | 1610 | free(tev->group); |
1521 | if (tev->group) | 1611 | free(tev->point.symbol); |
1522 | free(tev->group); | 1612 | free(tev->point.module); |
1523 | if (tev->point.symbol) | ||
1524 | free(tev->point.symbol); | ||
1525 | if (tev->point.module) | ||
1526 | free(tev->point.module); | ||
1527 | for (i = 0; i < tev->nargs; i++) { | 1613 | for (i = 0; i < tev->nargs; i++) { |
1528 | if (tev->args[i].name) | 1614 | free(tev->args[i].name); |
1529 | free(tev->args[i].name); | 1615 | free(tev->args[i].value); |
1530 | if (tev->args[i].value) | 1616 | free(tev->args[i].type); |
1531 | free(tev->args[i].value); | ||
1532 | if (tev->args[i].type) | ||
1533 | free(tev->args[i].type); | ||
1534 | ref = tev->args[i].ref; | 1617 | ref = tev->args[i].ref; |
1535 | while (ref) { | 1618 | while (ref) { |
1536 | next = ref->next; | 1619 | next = ref->next; |
@@ -1538,8 +1621,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) | |||
1538 | ref = next; | 1621 | ref = next; |
1539 | } | 1622 | } |
1540 | } | 1623 | } |
1541 | if (tev->args) | 1624 | free(tev->args); |
1542 | free(tev->args); | ||
1543 | memset(tev, 0, sizeof(*tev)); | 1625 | memset(tev, 0, sizeof(*tev)); |
1544 | } | 1626 | } |
1545 | 1627 | ||
@@ -1913,14 +1995,29 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, | |||
1913 | int max_tevs, const char *target) | 1995 | int max_tevs, const char *target) |
1914 | { | 1996 | { |
1915 | struct symbol *sym; | 1997 | struct symbol *sym; |
1916 | int ret = 0, i; | 1998 | int ret, i; |
1917 | struct probe_trace_event *tev; | 1999 | struct probe_trace_event *tev; |
1918 | 2000 | ||
2001 | if (pev->uprobes && !pev->group) { | ||
2002 | /* Replace group name if not given */ | ||
2003 | ret = convert_exec_to_group(target, &pev->group); | ||
2004 | if (ret != 0) { | ||
2005 | pr_warning("Failed to make a group name.\n"); | ||
2006 | return ret; | ||
2007 | } | ||
2008 | } | ||
2009 | |||
1919 | /* Convert perf_probe_event with debuginfo */ | 2010 | /* Convert perf_probe_event with debuginfo */ |
1920 | ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); | 2011 | ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); |
1921 | if (ret != 0) | 2012 | if (ret != 0) |
1922 | return ret; /* Found in debuginfo or got an error */ | 2013 | return ret; /* Found in debuginfo or got an error */ |
1923 | 2014 | ||
2015 | if (pev->uprobes) { | ||
2016 | ret = convert_name_to_addr(pev, target); | ||
2017 | if (ret < 0) | ||
2018 | return ret; | ||
2019 | } | ||
2020 | |||
1924 | /* Allocate trace event buffer */ | 2021 | /* Allocate trace event buffer */ |
1925 | tev = *tevs = zalloc(sizeof(struct probe_trace_event)); | 2022 | tev = *tevs = zalloc(sizeof(struct probe_trace_event)); |
1926 | if (tev == NULL) | 2023 | if (tev == NULL) |
@@ -2056,7 +2153,7 @@ end: | |||
2056 | for (i = 0; i < npevs; i++) { | 2153 | for (i = 0; i < npevs; i++) { |
2057 | for (j = 0; j < pkgs[i].ntevs; j++) | 2154 | for (j = 0; j < pkgs[i].ntevs; j++) |
2058 | clear_probe_trace_event(&pkgs[i].tevs[j]); | 2155 | clear_probe_trace_event(&pkgs[i].tevs[j]); |
2059 | free(pkgs[i].tevs); | 2156 | zfree(&pkgs[i].tevs); |
2060 | } | 2157 | } |
2061 | free(pkgs); | 2158 | free(pkgs); |
2062 | 2159 | ||
@@ -2281,7 +2378,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
2281 | struct perf_probe_point *pp = &pev->point; | 2378 | struct perf_probe_point *pp = &pev->point; |
2282 | struct symbol *sym; | 2379 | struct symbol *sym; |
2283 | struct map *map = NULL; | 2380 | struct map *map = NULL; |
2284 | char *function = NULL, *name = NULL; | 2381 | char *function = NULL; |
2285 | int ret = -EINVAL; | 2382 | int ret = -EINVAL; |
2286 | unsigned long long vaddr = 0; | 2383 | unsigned long long vaddr = 0; |
2287 | 2384 | ||
@@ -2297,12 +2394,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
2297 | goto out; | 2394 | goto out; |
2298 | } | 2395 | } |
2299 | 2396 | ||
2300 | name = realpath(exec, NULL); | 2397 | map = dso__new_map(exec); |
2301 | if (!name) { | ||
2302 | pr_warning("Cannot find realpath for %s.\n", exec); | ||
2303 | goto out; | ||
2304 | } | ||
2305 | map = dso__new_map(name); | ||
2306 | if (!map) { | 2398 | if (!map) { |
2307 | pr_warning("Cannot find appropriate DSO for %s.\n", exec); | 2399 | pr_warning("Cannot find appropriate DSO for %s.\n", exec); |
2308 | goto out; | 2400 | goto out; |
@@ -2367,7 +2459,5 @@ out: | |||
2367 | } | 2459 | } |
2368 | if (function) | 2460 | if (function) |
2369 | free(function); | 2461 | free(function); |
2370 | if (name) | ||
2371 | free(name); | ||
2372 | return ret; | 2462 | return ret; |
2373 | } | 2463 | } |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index f9f3de8b4220..d481c46e0796 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -12,6 +12,7 @@ struct probe_trace_point { | |||
12 | char *symbol; /* Base symbol */ | 12 | char *symbol; /* Base symbol */ |
13 | char *module; /* Module name */ | 13 | char *module; /* Module name */ |
14 | unsigned long offset; /* Offset from symbol */ | 14 | unsigned long offset; /* Offset from symbol */ |
15 | unsigned long address; /* Actual address of the trace point */ | ||
15 | bool retprobe; /* Return probe flag */ | 16 | bool retprobe; /* Return probe flag */ |
16 | }; | 17 | }; |
17 | 18 | ||
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index ffb657ffd327..061edb162b5b 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -226,10 +226,8 @@ struct debuginfo *debuginfo__new(const char *path) | |||
226 | if (!dbg) | 226 | if (!dbg) |
227 | return NULL; | 227 | return NULL; |
228 | 228 | ||
229 | if (debuginfo__init_offline_dwarf(dbg, path) < 0) { | 229 | if (debuginfo__init_offline_dwarf(dbg, path) < 0) |
230 | free(dbg); | 230 | zfree(&dbg); |
231 | dbg = NULL; | ||
232 | } | ||
233 | 231 | ||
234 | return dbg; | 232 | return dbg; |
235 | } | 233 | } |
@@ -241,10 +239,8 @@ struct debuginfo *debuginfo__new_online_kernel(unsigned long addr) | |||
241 | if (!dbg) | 239 | if (!dbg) |
242 | return NULL; | 240 | return NULL; |
243 | 241 | ||
244 | if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) { | 242 | if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) |
245 | free(dbg); | 243 | zfree(&dbg); |
246 | dbg = NULL; | ||
247 | } | ||
248 | 244 | ||
249 | return dbg; | 245 | return dbg; |
250 | } | 246 | } |
@@ -729,6 +725,7 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, | |||
729 | return -ENOENT; | 725 | return -ENOENT; |
730 | } | 726 | } |
731 | tp->offset = (unsigned long)(paddr - sym.st_value); | 727 | tp->offset = (unsigned long)(paddr - sym.st_value); |
728 | tp->address = (unsigned long)paddr; | ||
732 | tp->symbol = strdup(symbol); | 729 | tp->symbol = strdup(symbol); |
733 | if (!tp->symbol) | 730 | if (!tp->symbol) |
734 | return -ENOMEM; | 731 | return -ENOMEM; |
@@ -1301,8 +1298,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, | |||
1301 | 1298 | ||
1302 | ret = debuginfo__find_probes(dbg, &tf.pf); | 1299 | ret = debuginfo__find_probes(dbg, &tf.pf); |
1303 | if (ret < 0) { | 1300 | if (ret < 0) { |
1304 | free(*tevs); | 1301 | zfree(tevs); |
1305 | *tevs = NULL; | ||
1306 | return ret; | 1302 | return ret; |
1307 | } | 1303 | } |
1308 | 1304 | ||
@@ -1413,13 +1409,10 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg, | |||
1413 | if (ret < 0) { | 1409 | if (ret < 0) { |
1414 | /* Free vlist for error */ | 1410 | /* Free vlist for error */ |
1415 | while (af.nvls--) { | 1411 | while (af.nvls--) { |
1416 | if (af.vls[af.nvls].point.symbol) | 1412 | zfree(&af.vls[af.nvls].point.symbol); |
1417 | free(af.vls[af.nvls].point.symbol); | 1413 | strlist__delete(af.vls[af.nvls].vars); |
1418 | if (af.vls[af.nvls].vars) | ||
1419 | strlist__delete(af.vls[af.nvls].vars); | ||
1420 | } | 1414 | } |
1421 | free(af.vls); | 1415 | zfree(vls); |
1422 | *vls = NULL; | ||
1423 | return ret; | 1416 | return ret; |
1424 | } | 1417 | } |
1425 | 1418 | ||
@@ -1523,10 +1516,7 @@ post: | |||
1523 | if (fname) { | 1516 | if (fname) { |
1524 | ppt->file = strdup(fname); | 1517 | ppt->file = strdup(fname); |
1525 | if (ppt->file == NULL) { | 1518 | if (ppt->file == NULL) { |
1526 | if (ppt->function) { | 1519 | zfree(&ppt->function); |
1527 | free(ppt->function); | ||
1528 | ppt->function = NULL; | ||
1529 | } | ||
1530 | ret = -ENOMEM; | 1520 | ret = -ENOMEM; |
1531 | goto end; | 1521 | goto end; |
1532 | } | 1522 | } |
@@ -1580,8 +1570,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | |||
1580 | else | 1570 | else |
1581 | ret = 0; /* Lines are not found */ | 1571 | ret = 0; /* Lines are not found */ |
1582 | else { | 1572 | else { |
1583 | free(lf->lr->path); | 1573 | zfree(&lf->lr->path); |
1584 | lf->lr->path = NULL; | ||
1585 | } | 1574 | } |
1586 | return ret; | 1575 | return ret; |
1587 | } | 1576 | } |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index e5104538c354..104a47563d39 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -74,8 +74,7 @@ bool perf_can_sample_identifier(void) | |||
74 | return perf_probe_api(perf_probe_sample_identifier); | 74 | return perf_probe_api(perf_probe_sample_identifier); |
75 | } | 75 | } |
76 | 76 | ||
77 | void perf_evlist__config(struct perf_evlist *evlist, | 77 | void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) |
78 | struct perf_record_opts *opts) | ||
79 | { | 78 | { |
80 | struct perf_evsel *evsel; | 79 | struct perf_evsel *evsel; |
81 | bool use_sample_identifier = false; | 80 | bool use_sample_identifier = false; |
@@ -123,7 +122,7 @@ static int get_max_rate(unsigned int *rate) | |||
123 | return filename__read_int(path, (int *) rate); | 122 | return filename__read_int(path, (int *) rate); |
124 | } | 123 | } |
125 | 124 | ||
126 | static int perf_record_opts__config_freq(struct perf_record_opts *opts) | 125 | static int record_opts__config_freq(struct record_opts *opts) |
127 | { | 126 | { |
128 | bool user_freq = opts->user_freq != UINT_MAX; | 127 | bool user_freq = opts->user_freq != UINT_MAX; |
129 | unsigned int max_rate; | 128 | unsigned int max_rate; |
@@ -173,9 +172,9 @@ static int perf_record_opts__config_freq(struct perf_record_opts *opts) | |||
173 | return 0; | 172 | return 0; |
174 | } | 173 | } |
175 | 174 | ||
176 | int perf_record_opts__config(struct perf_record_opts *opts) | 175 | int record_opts__config(struct record_opts *opts) |
177 | { | 176 | { |
178 | return perf_record_opts__config_freq(opts); | 177 | return record_opts__config_freq(opts); |
179 | } | 178 | } |
180 | 179 | ||
181 | bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) | 180 | bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) |
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index d5e5969f6fea..e108207c5de0 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
@@ -194,8 +194,7 @@ static void define_event_symbols(struct event_format *event, | |||
194 | zero_flag_atom = 0; | 194 | zero_flag_atom = 0; |
195 | break; | 195 | break; |
196 | case PRINT_FIELD: | 196 | case PRINT_FIELD: |
197 | if (cur_field_name) | 197 | free(cur_field_name); |
198 | free(cur_field_name); | ||
199 | cur_field_name = strdup(args->field.name); | 198 | cur_field_name = strdup(args->field.name); |
200 | break; | 199 | break; |
201 | case PRINT_FLAGS: | 200 | case PRINT_FLAGS: |
@@ -257,12 +256,9 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel) | |||
257 | return event; | 256 | return event; |
258 | } | 257 | } |
259 | 258 | ||
260 | static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, | 259 | static void perl_process_tracepoint(struct perf_sample *sample, |
261 | struct perf_sample *sample, | ||
262 | struct perf_evsel *evsel, | 260 | struct perf_evsel *evsel, |
263 | struct machine *machine __maybe_unused, | 261 | struct thread *thread) |
264 | struct thread *thread, | ||
265 | struct addr_location *al) | ||
266 | { | 262 | { |
267 | struct format_field *field; | 263 | struct format_field *field; |
268 | static char handler[256]; | 264 | static char handler[256]; |
@@ -349,10 +345,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, | |||
349 | 345 | ||
350 | static void perl_process_event_generic(union perf_event *event, | 346 | static void perl_process_event_generic(union perf_event *event, |
351 | struct perf_sample *sample, | 347 | struct perf_sample *sample, |
352 | struct perf_evsel *evsel, | 348 | struct perf_evsel *evsel) |
353 | struct machine *machine __maybe_unused, | ||
354 | struct thread *thread __maybe_unused, | ||
355 | struct addr_location *al __maybe_unused) | ||
356 | { | 349 | { |
357 | dSP; | 350 | dSP; |
358 | 351 | ||
@@ -377,12 +370,11 @@ static void perl_process_event_generic(union perf_event *event, | |||
377 | static void perl_process_event(union perf_event *event, | 370 | static void perl_process_event(union perf_event *event, |
378 | struct perf_sample *sample, | 371 | struct perf_sample *sample, |
379 | struct perf_evsel *evsel, | 372 | struct perf_evsel *evsel, |
380 | struct machine *machine, | ||
381 | struct thread *thread, | 373 | struct thread *thread, |
382 | struct addr_location *al) | 374 | struct addr_location *al __maybe_unused) |
383 | { | 375 | { |
384 | perl_process_tracepoint(event, sample, evsel, machine, thread, al); | 376 | perl_process_tracepoint(sample, evsel, thread); |
385 | perl_process_event_generic(event, sample, evsel, machine, thread, al); | 377 | perl_process_event_generic(event, sample, evsel); |
386 | } | 378 | } |
387 | 379 | ||
388 | static void run_start_sub(void) | 380 | static void run_start_sub(void) |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 53c20e7fd900..cd9774df3750 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -161,8 +161,7 @@ static void define_event_symbols(struct event_format *event, | |||
161 | zero_flag_atom = 0; | 161 | zero_flag_atom = 0; |
162 | break; | 162 | break; |
163 | case PRINT_FIELD: | 163 | case PRINT_FIELD: |
164 | if (cur_field_name) | 164 | free(cur_field_name); |
165 | free(cur_field_name); | ||
166 | cur_field_name = strdup(args->field.name); | 165 | cur_field_name = strdup(args->field.name); |
167 | break; | 166 | break; |
168 | case PRINT_FLAGS: | 167 | case PRINT_FLAGS: |
@@ -231,13 +230,10 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel) | |||
231 | return event; | 230 | return event; |
232 | } | 231 | } |
233 | 232 | ||
234 | static void python_process_tracepoint(union perf_event *perf_event | 233 | static void python_process_tracepoint(struct perf_sample *sample, |
235 | __maybe_unused, | 234 | struct perf_evsel *evsel, |
236 | struct perf_sample *sample, | 235 | struct thread *thread, |
237 | struct perf_evsel *evsel, | 236 | struct addr_location *al) |
238 | struct machine *machine __maybe_unused, | ||
239 | struct thread *thread, | ||
240 | struct addr_location *al) | ||
241 | { | 237 | { |
242 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; | 238 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; |
243 | static char handler_name[256]; | 239 | static char handler_name[256]; |
@@ -351,11 +347,8 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
351 | Py_DECREF(t); | 347 | Py_DECREF(t); |
352 | } | 348 | } |
353 | 349 | ||
354 | static void python_process_general_event(union perf_event *perf_event | 350 | static void python_process_general_event(struct perf_sample *sample, |
355 | __maybe_unused, | ||
356 | struct perf_sample *sample, | ||
357 | struct perf_evsel *evsel, | 351 | struct perf_evsel *evsel, |
358 | struct machine *machine __maybe_unused, | ||
359 | struct thread *thread, | 352 | struct thread *thread, |
360 | struct addr_location *al) | 353 | struct addr_location *al) |
361 | { | 354 | { |
@@ -411,22 +404,19 @@ exit: | |||
411 | Py_DECREF(t); | 404 | Py_DECREF(t); |
412 | } | 405 | } |
413 | 406 | ||
414 | static void python_process_event(union perf_event *perf_event, | 407 | static void python_process_event(union perf_event *event __maybe_unused, |
415 | struct perf_sample *sample, | 408 | struct perf_sample *sample, |
416 | struct perf_evsel *evsel, | 409 | struct perf_evsel *evsel, |
417 | struct machine *machine, | ||
418 | struct thread *thread, | 410 | struct thread *thread, |
419 | struct addr_location *al) | 411 | struct addr_location *al) |
420 | { | 412 | { |
421 | switch (evsel->attr.type) { | 413 | switch (evsel->attr.type) { |
422 | case PERF_TYPE_TRACEPOINT: | 414 | case PERF_TYPE_TRACEPOINT: |
423 | python_process_tracepoint(perf_event, sample, evsel, | 415 | python_process_tracepoint(sample, evsel, thread, al); |
424 | machine, thread, al); | ||
425 | break; | 416 | break; |
426 | /* Reserve for future process_hw/sw/raw APIs */ | 417 | /* Reserve for future process_hw/sw/raw APIs */ |
427 | default: | 418 | default: |
428 | python_process_general_event(perf_event, sample, evsel, | 419 | python_process_general_event(sample, evsel, thread, al); |
429 | machine, thread, al); | ||
430 | } | 420 | } |
431 | } | 421 | } |
432 | 422 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 989b2e377626..8ffe29c55d0f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -132,18 +132,18 @@ static void perf_session__delete_threads(struct perf_session *session) | |||
132 | 132 | ||
133 | static void perf_session_env__delete(struct perf_session_env *env) | 133 | static void perf_session_env__delete(struct perf_session_env *env) |
134 | { | 134 | { |
135 | free(env->hostname); | 135 | zfree(&env->hostname); |
136 | free(env->os_release); | 136 | zfree(&env->os_release); |
137 | free(env->version); | 137 | zfree(&env->version); |
138 | free(env->arch); | 138 | zfree(&env->arch); |
139 | free(env->cpu_desc); | 139 | zfree(&env->cpu_desc); |
140 | free(env->cpuid); | 140 | zfree(&env->cpuid); |
141 | 141 | ||
142 | free(env->cmdline); | 142 | zfree(&env->cmdline); |
143 | free(env->sibling_cores); | 143 | zfree(&env->sibling_cores); |
144 | free(env->sibling_threads); | 144 | zfree(&env->sibling_threads); |
145 | free(env->numa_nodes); | 145 | zfree(&env->numa_nodes); |
146 | free(env->pmu_mappings); | 146 | zfree(&env->pmu_mappings); |
147 | } | 147 | } |
148 | 148 | ||
149 | void perf_session__delete(struct perf_session *session) | 149 | void perf_session__delete(struct perf_session *session) |
@@ -830,6 +830,7 @@ static struct machine * | |||
830 | struct perf_sample *sample) | 830 | struct perf_sample *sample) |
831 | { | 831 | { |
832 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 832 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
833 | struct machine *machine; | ||
833 | 834 | ||
834 | if (perf_guest && | 835 | if (perf_guest && |
835 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || | 836 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || |
@@ -842,7 +843,11 @@ static struct machine * | |||
842 | else | 843 | else |
843 | pid = sample->pid; | 844 | pid = sample->pid; |
844 | 845 | ||
845 | return perf_session__findnew_machine(session, pid); | 846 | machine = perf_session__find_machine(session, pid); |
847 | if (!machine) | ||
848 | machine = perf_session__findnew_machine(session, | ||
849 | DEFAULT_GUEST_KERNEL_ID); | ||
850 | return machine; | ||
846 | } | 851 | } |
847 | 852 | ||
848 | return &session->machines.host; | 853 | return &session->machines.host; |
@@ -1467,7 +1472,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
1467 | } | 1472 | } |
1468 | 1473 | ||
1469 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | 1474 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, |
1470 | struct machine *machine, struct addr_location *al, | 1475 | struct addr_location *al, |
1471 | unsigned int print_opts, unsigned int stack_depth) | 1476 | unsigned int print_opts, unsigned int stack_depth) |
1472 | { | 1477 | { |
1473 | struct callchain_cursor_node *node; | 1478 | struct callchain_cursor_node *node; |
@@ -1482,7 +1487,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | |||
1482 | if (symbol_conf.use_callchain && sample->callchain) { | 1487 | if (symbol_conf.use_callchain && sample->callchain) { |
1483 | struct addr_location node_al; | 1488 | struct addr_location node_al; |
1484 | 1489 | ||
1485 | if (machine__resolve_callchain(machine, evsel, al->thread, | 1490 | if (machine__resolve_callchain(al->machine, evsel, al->thread, |
1486 | sample, NULL, NULL, | 1491 | sample, NULL, NULL, |
1487 | PERF_MAX_STACK_DEPTH) != 0) { | 1492 | PERF_MAX_STACK_DEPTH) != 0) { |
1488 | if (verbose) | 1493 | if (verbose) |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 9c25d49900af..3140f8ae6148 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -106,7 +106,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
106 | unsigned int type); | 106 | unsigned int type); |
107 | 107 | ||
108 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | 108 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, |
109 | struct machine *machine, struct addr_location *al, | 109 | struct addr_location *al, |
110 | unsigned int print_opts, unsigned int stack_depth); | 110 | unsigned int print_opts, unsigned int stack_depth); |
111 | 111 | ||
112 | int perf_session__cpu_bitmap(struct perf_session *session, | 112 | int perf_session__cpu_bitmap(struct perf_session *session, |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 8b0bb1f4494a..635cd8f8b22e 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -13,6 +13,7 @@ int have_ignore_callees = 0; | |||
13 | int sort__need_collapse = 0; | 13 | int sort__need_collapse = 0; |
14 | int sort__has_parent = 0; | 14 | int sort__has_parent = 0; |
15 | int sort__has_sym = 0; | 15 | int sort__has_sym = 0; |
16 | int sort__has_dso = 0; | ||
16 | enum sort_mode sort__mode = SORT_MODE__NORMAL; | 17 | enum sort_mode sort__mode = SORT_MODE__NORMAL; |
17 | 18 | ||
18 | enum sort_type sort__first_dimension; | 19 | enum sort_type sort__first_dimension; |
@@ -161,6 +162,11 @@ struct sort_entry sort_dso = { | |||
161 | 162 | ||
162 | /* --sort symbol */ | 163 | /* --sort symbol */ |
163 | 164 | ||
165 | static int64_t _sort__addr_cmp(u64 left_ip, u64 right_ip) | ||
166 | { | ||
167 | return (int64_t)(right_ip - left_ip); | ||
168 | } | ||
169 | |||
164 | static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) | 170 | static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) |
165 | { | 171 | { |
166 | u64 ip_l, ip_r; | 172 | u64 ip_l, ip_r; |
@@ -183,15 +189,17 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) | |||
183 | int64_t ret; | 189 | int64_t ret; |
184 | 190 | ||
185 | if (!left->ms.sym && !right->ms.sym) | 191 | if (!left->ms.sym && !right->ms.sym) |
186 | return right->level - left->level; | 192 | return _sort__addr_cmp(left->ip, right->ip); |
187 | 193 | ||
188 | /* | 194 | /* |
189 | * comparing symbol address alone is not enough since it's a | 195 | * comparing symbol address alone is not enough since it's a |
190 | * relative address within a dso. | 196 | * relative address within a dso. |
191 | */ | 197 | */ |
192 | ret = sort__dso_cmp(left, right); | 198 | if (!sort__has_dso) { |
193 | if (ret != 0) | 199 | ret = sort__dso_cmp(left, right); |
194 | return ret; | 200 | if (ret != 0) |
201 | return ret; | ||
202 | } | ||
195 | 203 | ||
196 | return _sort__sym_cmp(left->ms.sym, right->ms.sym); | 204 | return _sort__sym_cmp(left->ms.sym, right->ms.sym); |
197 | } | 205 | } |
@@ -372,7 +380,7 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
372 | struct addr_map_symbol *from_r = &right->branch_info->from; | 380 | struct addr_map_symbol *from_r = &right->branch_info->from; |
373 | 381 | ||
374 | if (!from_l->sym && !from_r->sym) | 382 | if (!from_l->sym && !from_r->sym) |
375 | return right->level - left->level; | 383 | return _sort__addr_cmp(from_l->addr, from_r->addr); |
376 | 384 | ||
377 | return _sort__sym_cmp(from_l->sym, from_r->sym); | 385 | return _sort__sym_cmp(from_l->sym, from_r->sym); |
378 | } | 386 | } |
@@ -384,7 +392,7 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
384 | struct addr_map_symbol *to_r = &right->branch_info->to; | 392 | struct addr_map_symbol *to_r = &right->branch_info->to; |
385 | 393 | ||
386 | if (!to_l->sym && !to_r->sym) | 394 | if (!to_l->sym && !to_r->sym) |
387 | return right->level - left->level; | 395 | return _sort__addr_cmp(to_l->addr, to_r->addr); |
388 | 396 | ||
389 | return _sort__sym_cmp(to_l->sym, to_r->sym); | 397 | return _sort__sym_cmp(to_l->sym, to_r->sym); |
390 | } | 398 | } |
@@ -1056,6 +1064,8 @@ int sort_dimension__add(const char *tok) | |||
1056 | sort__has_parent = 1; | 1064 | sort__has_parent = 1; |
1057 | } else if (sd->entry == &sort_sym) { | 1065 | } else if (sd->entry == &sort_sym) { |
1058 | sort__has_sym = 1; | 1066 | sort__has_sym = 1; |
1067 | } else if (sd->entry == &sort_dso) { | ||
1068 | sort__has_dso = 1; | ||
1059 | } | 1069 | } |
1060 | 1070 | ||
1061 | __sort_dimension__add(sd, i); | 1071 | __sort_dimension__add(sd, i); |
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 58b2bd8f38c9..7e67879ebd25 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
@@ -129,7 +129,7 @@ static struct a2l_data *addr2line_init(const char *path) | |||
129 | 129 | ||
130 | out: | 130 | out: |
131 | if (a2l) { | 131 | if (a2l) { |
132 | free((void *)a2l->input); | 132 | zfree((void **)&a2l->input); |
133 | free(a2l); | 133 | free(a2l); |
134 | } | 134 | } |
135 | bfd_close(abfd); | 135 | bfd_close(abfd); |
@@ -140,8 +140,8 @@ static void addr2line_cleanup(struct a2l_data *a2l) | |||
140 | { | 140 | { |
141 | if (a2l->abfd) | 141 | if (a2l->abfd) |
142 | bfd_close(a2l->abfd); | 142 | bfd_close(a2l->abfd); |
143 | free((void *)a2l->input); | 143 | zfree((void **)&a2l->input); |
144 | free(a2l->syms); | 144 | zfree(&a2l->syms); |
145 | free(a2l); | 145 | free(a2l); |
146 | } | 146 | } |
147 | 147 | ||
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index cfa906882e2c..4abe23550c73 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c | |||
@@ -28,7 +28,7 @@ void strbuf_init(struct strbuf *sb, ssize_t hint) | |||
28 | void strbuf_release(struct strbuf *sb) | 28 | void strbuf_release(struct strbuf *sb) |
29 | { | 29 | { |
30 | if (sb->alloc) { | 30 | if (sb->alloc) { |
31 | free(sb->buf); | 31 | zfree(&sb->buf); |
32 | strbuf_init(sb, 0); | 32 | strbuf_init(sb, 0); |
33 | } | 33 | } |
34 | } | 34 | } |
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c index 3edd0538161f..79a757a2a15c 100644 --- a/tools/perf/util/strfilter.c +++ b/tools/perf/util/strfilter.c | |||
@@ -14,7 +14,7 @@ static void strfilter_node__delete(struct strfilter_node *node) | |||
14 | { | 14 | { |
15 | if (node) { | 15 | if (node) { |
16 | if (node->p && !is_operator(*node->p)) | 16 | if (node->p && !is_operator(*node->p)) |
17 | free((char *)node->p); | 17 | zfree((char **)&node->p); |
18 | strfilter_node__delete(node->l); | 18 | strfilter_node__delete(node->l); |
19 | strfilter_node__delete(node->r); | 19 | strfilter_node__delete(node->r); |
20 | free(node); | 20 | free(node); |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index f0b0c008c507..2553e5b55b89 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -128,7 +128,7 @@ void argv_free(char **argv) | |||
128 | { | 128 | { |
129 | char **p; | 129 | char **p; |
130 | for (p = argv; *p; p++) | 130 | for (p = argv; *p; p++) |
131 | free(*p); | 131 | zfree(p); |
132 | 132 | ||
133 | free(argv); | 133 | free(argv); |
134 | } | 134 | } |
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index eabdce0a2daa..61a90bf24b4d 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "strlist.h" | 7 | #include "strlist.h" |
8 | #include "util.h" | ||
8 | #include <errno.h> | 9 | #include <errno.h> |
9 | #include <stdio.h> | 10 | #include <stdio.h> |
10 | #include <stdlib.h> | 11 | #include <stdlib.h> |
@@ -38,7 +39,7 @@ out_delete: | |||
38 | static void str_node__delete(struct str_node *snode, bool dupstr) | 39 | static void str_node__delete(struct str_node *snode, bool dupstr) |
39 | { | 40 | { |
40 | if (dupstr) | 41 | if (dupstr) |
41 | free((void *)snode->s); | 42 | zfree((void **)&snode->s); |
42 | free(snode); | 43 | free(snode); |
43 | } | 44 | } |
44 | 45 | ||
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 56a84f2cc46d..43262b83c541 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "perf.h" | 22 | #include "perf.h" |
23 | #include "svghelper.h" | 23 | #include "svghelper.h" |
24 | #include "util.h" | ||
24 | #include "cpumap.h" | 25 | #include "cpumap.h" |
25 | 26 | ||
26 | static u64 first_time, last_time; | 27 | static u64 first_time, last_time; |
@@ -708,8 +709,8 @@ int svg_build_topology_map(char *sib_core, int sib_core_nr, | |||
708 | return 0; | 709 | return 0; |
709 | 710 | ||
710 | exit: | 711 | exit: |
711 | free(t.sib_core); | 712 | zfree(&t.sib_core); |
712 | free(t.sib_thr); | 713 | zfree(&t.sib_thr); |
713 | 714 | ||
714 | return -1; | 715 | return -1; |
715 | } | 716 | } |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index bf0ce29567b6..4b0a127a4d3b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -554,7 +554,7 @@ bool symsrc__has_symtab(struct symsrc *ss) | |||
554 | 554 | ||
555 | void symsrc__destroy(struct symsrc *ss) | 555 | void symsrc__destroy(struct symsrc *ss) |
556 | { | 556 | { |
557 | free(ss->name); | 557 | zfree(&ss->name); |
558 | elf_end(ss->elf); | 558 | elf_end(ss->elf); |
559 | close(ss->fd); | 559 | close(ss->fd); |
560 | } | 560 | } |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index ac7070a2f2b6..bd15f490d04f 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include "symbol.h" | 1 | #include "symbol.h" |
2 | #include "util.h" | ||
2 | 3 | ||
3 | #include <stdio.h> | 4 | #include <stdio.h> |
4 | #include <fcntl.h> | 5 | #include <fcntl.h> |
@@ -275,7 +276,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused) | |||
275 | 276 | ||
276 | void symsrc__destroy(struct symsrc *ss) | 277 | void symsrc__destroy(struct symsrc *ss) |
277 | { | 278 | { |
278 | free(ss->name); | 279 | zfree(&ss->name); |
279 | close(ss->fd); | 280 | close(ss->fd); |
280 | } | 281 | } |
281 | 282 | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 923d00040bbf..39ce9adbaaf0 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -796,7 +796,7 @@ static void delete_modules(struct rb_root *modules) | |||
796 | mi = rb_entry(next, struct module_info, rb_node); | 796 | mi = rb_entry(next, struct module_info, rb_node); |
797 | next = rb_next(&mi->rb_node); | 797 | next = rb_next(&mi->rb_node); |
798 | rb_erase(&mi->rb_node, modules); | 798 | rb_erase(&mi->rb_node, modules); |
799 | free(mi->name); | 799 | zfree(&mi->name); |
800 | free(mi); | 800 | free(mi); |
801 | } | 801 | } |
802 | } | 802 | } |
@@ -1621,13 +1621,10 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, | |||
1621 | 1621 | ||
1622 | static void vmlinux_path__exit(void) | 1622 | static void vmlinux_path__exit(void) |
1623 | { | 1623 | { |
1624 | while (--vmlinux_path__nr_entries >= 0) { | 1624 | while (--vmlinux_path__nr_entries >= 0) |
1625 | free(vmlinux_path[vmlinux_path__nr_entries]); | 1625 | zfree(&vmlinux_path[vmlinux_path__nr_entries]); |
1626 | vmlinux_path[vmlinux_path__nr_entries] = NULL; | ||
1627 | } | ||
1628 | 1626 | ||
1629 | free(vmlinux_path); | 1627 | zfree(&vmlinux_path); |
1630 | vmlinux_path = NULL; | ||
1631 | } | 1628 | } |
1632 | 1629 | ||
1633 | static int vmlinux_path__init(void) | 1630 | static int vmlinux_path__init(void) |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 8a9d910c5345..cbd680361806 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -164,6 +164,7 @@ struct mem_info { | |||
164 | }; | 164 | }; |
165 | 165 | ||
166 | struct addr_location { | 166 | struct addr_location { |
167 | struct machine *machine; | ||
167 | struct thread *thread; | 168 | struct thread *thread; |
168 | struct map *map; | 169 | struct map *map; |
169 | struct symbol *sym; | 170 | struct symbol *sym; |
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 9b5f856cc280..5d3215912105 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "strlist.h" | 9 | #include "strlist.h" |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include "thread_map.h" | 11 | #include "thread_map.h" |
12 | #include "util.h" | ||
12 | 13 | ||
13 | /* Skip "." and ".." directories */ | 14 | /* Skip "." and ".." directories */ |
14 | static int filter(const struct dirent *dir) | 15 | static int filter(const struct dirent *dir) |
@@ -40,7 +41,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid) | |||
40 | } | 41 | } |
41 | 42 | ||
42 | for (i=0; i<items; i++) | 43 | for (i=0; i<items; i++) |
43 | free(namelist[i]); | 44 | zfree(&namelist[i]); |
44 | free(namelist); | 45 | free(namelist); |
45 | 46 | ||
46 | return threads; | 47 | return threads; |
@@ -117,7 +118,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) | |||
117 | threads->map[threads->nr + i] = atoi(namelist[i]->d_name); | 118 | threads->map[threads->nr + i] = atoi(namelist[i]->d_name); |
118 | 119 | ||
119 | for (i = 0; i < items; i++) | 120 | for (i = 0; i < items; i++) |
120 | free(namelist[i]); | 121 | zfree(&namelist[i]); |
121 | free(namelist); | 122 | free(namelist); |
122 | 123 | ||
123 | threads->nr += items; | 124 | threads->nr += items; |
@@ -134,12 +135,11 @@ out_free_threads: | |||
134 | 135 | ||
135 | out_free_namelist: | 136 | out_free_namelist: |
136 | for (i = 0; i < items; i++) | 137 | for (i = 0; i < items; i++) |
137 | free(namelist[i]); | 138 | zfree(&namelist[i]); |
138 | free(namelist); | 139 | free(namelist); |
139 | 140 | ||
140 | out_free_closedir: | 141 | out_free_closedir: |
141 | free(threads); | 142 | zfree(&threads); |
142 | threads = NULL; | ||
143 | goto out_closedir; | 143 | goto out_closedir; |
144 | } | 144 | } |
145 | 145 | ||
@@ -194,7 +194,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) | |||
194 | 194 | ||
195 | for (i = 0; i < items; i++) { | 195 | for (i = 0; i < items; i++) { |
196 | threads->map[j++] = atoi(namelist[i]->d_name); | 196 | threads->map[j++] = atoi(namelist[i]->d_name); |
197 | free(namelist[i]); | 197 | zfree(&namelist[i]); |
198 | } | 198 | } |
199 | threads->nr = total_tasks; | 199 | threads->nr = total_tasks; |
200 | free(namelist); | 200 | free(namelist); |
@@ -206,12 +206,11 @@ out: | |||
206 | 206 | ||
207 | out_free_namelist: | 207 | out_free_namelist: |
208 | for (i = 0; i < items; i++) | 208 | for (i = 0; i < items; i++) |
209 | free(namelist[i]); | 209 | zfree(&namelist[i]); |
210 | free(namelist); | 210 | free(namelist); |
211 | 211 | ||
212 | out_free_threads: | 212 | out_free_threads: |
213 | free(threads); | 213 | zfree(&threads); |
214 | threads = NULL; | ||
215 | goto out; | 214 | goto out; |
216 | } | 215 | } |
217 | 216 | ||
@@ -262,8 +261,7 @@ out: | |||
262 | return threads; | 261 | return threads; |
263 | 262 | ||
264 | out_free_threads: | 263 | out_free_threads: |
265 | free(threads); | 264 | zfree(&threads); |
266 | threads = NULL; | ||
267 | goto out; | 265 | goto out; |
268 | } | 266 | } |
269 | 267 | ||
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index ce793c7dd23c..8e517def925b 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
@@ -26,7 +26,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
26 | float samples_per_sec; | 26 | float samples_per_sec; |
27 | float ksamples_per_sec; | 27 | float ksamples_per_sec; |
28 | float esamples_percent; | 28 | float esamples_percent; |
29 | struct perf_record_opts *opts = &top->record_opts; | 29 | struct record_opts *opts = &top->record_opts; |
30 | struct target *target = &opts->target; | 30 | struct target *target = &opts->target; |
31 | size_t ret = 0; | 31 | size_t ret = 0; |
32 | 32 | ||
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 88cfeaff600b..dab14d0ad3d0 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
@@ -14,7 +14,7 @@ struct perf_session; | |||
14 | struct perf_top { | 14 | struct perf_top { |
15 | struct perf_tool tool; | 15 | struct perf_tool tool; |
16 | struct perf_evlist *evlist; | 16 | struct perf_evlist *evlist; |
17 | struct perf_record_opts record_opts; | 17 | struct record_opts record_opts; |
18 | /* | 18 | /* |
19 | * Symbols will be added here in perf_event__process_sample and will | 19 | * Symbols will be added here in perf_event__process_sample and will |
20 | * get out after decayed. | 20 | * get out after decayed. |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index c354b95a2348..7e6fcfe8b438 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -397,8 +397,8 @@ put_tracepoints_path(struct tracepoint_path *tps) | |||
397 | struct tracepoint_path *t = tps; | 397 | struct tracepoint_path *t = tps; |
398 | 398 | ||
399 | tps = tps->next; | 399 | tps = tps->next; |
400 | free(t->name); | 400 | zfree(&t->name); |
401 | free(t->system); | 401 | zfree(&t->system); |
402 | free(t); | 402 | free(t); |
403 | } | 403 | } |
404 | } | 404 | } |
@@ -562,10 +562,8 @@ out: | |||
562 | output_fd = fd; | 562 | output_fd = fd; |
563 | } | 563 | } |
564 | 564 | ||
565 | if (err) { | 565 | if (err) |
566 | free(tdata); | 566 | zfree(&tdata); |
567 | tdata = NULL; | ||
568 | } | ||
569 | 567 | ||
570 | put_tracepoints_path(tps); | 568 | put_tracepoints_path(tps); |
571 | return tdata; | 569 | return tdata; |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 95199e4eea97..57aaccc1692e 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
@@ -38,9 +38,8 @@ static int stop_script_unsupported(void) | |||
38 | static void process_event_unsupported(union perf_event *event __maybe_unused, | 38 | static void process_event_unsupported(union perf_event *event __maybe_unused, |
39 | struct perf_sample *sample __maybe_unused, | 39 | struct perf_sample *sample __maybe_unused, |
40 | struct perf_evsel *evsel __maybe_unused, | 40 | struct perf_evsel *evsel __maybe_unused, |
41 | struct machine *machine __maybe_unused, | ||
42 | struct thread *thread __maybe_unused, | 41 | struct thread *thread __maybe_unused, |
43 | struct addr_location *al __maybe_unused) | 42 | struct addr_location *al __maybe_unused) |
44 | { | 43 | { |
45 | } | 44 | } |
46 | 45 | ||
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 3a01618c5b87..7b6d68688327 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
@@ -68,7 +68,6 @@ struct scripting_ops { | |||
68 | void (*process_event) (union perf_event *event, | 68 | void (*process_event) (union perf_event *event, |
69 | struct perf_sample *sample, | 69 | struct perf_sample *sample, |
70 | struct perf_evsel *evsel, | 70 | struct perf_evsel *evsel, |
71 | struct machine *machine, | ||
72 | struct thread *thread, | 71 | struct thread *thread, |
73 | struct addr_location *al); | 72 | struct addr_location *al); |
74 | int (*generate_script) (struct pevent *pevent, const char *outfile); | 73 | int (*generate_script) (struct pevent *pevent, const char *outfile); |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 9a2c268ad718..6995d66f225c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -186,6 +186,8 @@ static inline void *zalloc(size_t size) | |||
186 | return calloc(1, size); | 186 | return calloc(1, size); |
187 | } | 187 | } |
188 | 188 | ||
189 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | ||
190 | |||
189 | static inline int has_extension(const char *filename, const char *ext) | 191 | static inline int has_extension(const char *filename, const char *ext) |
190 | { | 192 | { |
191 | size_t len = strlen(filename); | 193 | size_t len = strlen(filename); |
diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 697c8b4e59cc..0fb3c1fcd3e6 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c | |||
@@ -31,14 +31,14 @@ void perf_read_values_destroy(struct perf_read_values *values) | |||
31 | return; | 31 | return; |
32 | 32 | ||
33 | for (i = 0; i < values->threads; i++) | 33 | for (i = 0; i < values->threads; i++) |
34 | free(values->value[i]); | 34 | zfree(&values->value[i]); |
35 | free(values->value); | 35 | zfree(&values->value); |
36 | free(values->pid); | 36 | zfree(&values->pid); |
37 | free(values->tid); | 37 | zfree(&values->tid); |
38 | free(values->counterrawid); | 38 | zfree(&values->counterrawid); |
39 | for (i = 0; i < values->counters; i++) | 39 | for (i = 0; i < values->counters; i++) |
40 | free(values->countername[i]); | 40 | zfree(&values->countername[i]); |
41 | free(values->countername); | 41 | zfree(&values->countername); |
42 | } | 42 | } |
43 | 43 | ||
44 | static void perf_read_values__enlarge_threads(struct perf_read_values *values) | 44 | static void perf_read_values__enlarge_threads(struct perf_read_values *values) |