perf annotate: Ensure init/exit for global options
[linux-2.6-block.git] / tools / perf / builtin-report.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
bf9e1876
IM
2/*
3 * builtin-report.c
4 *
5 * Builtin report command: Analyze the perf.data input file,
6 * look up and read DSOs and symbol information and display
7 * a histogram of results, along various sorting keys.
8 */
16f762a2 9#include "builtin.h"
53cb8bc2 10
41840d21 11#include "util/config.h"
bf9e1876 12
78f7defe 13#include "util/annotate.h"
8fc0321f 14#include "util/color.h"
4a3cec84 15#include "util/dso.h"
5da50258 16#include <linux/list.h>
43cbcd8a 17#include <linux/rbtree.h>
930f8b34 18#include <linux/err.h>
7f7c536f 19#include <linux/zalloc.h>
1101f69a 20#include "util/map.h"
a2928c42 21#include "util/symbol.h"
d3300a3c
ACM
22#include "util/map_symbol.h"
23#include "util/mem-events.h"
24#include "util/branch.h"
f55c5552 25#include "util/callchain.h"
8d513270 26#include "util/values.h"
8fa66bdc 27
53cb8bc2 28#include "perf.h"
8f28827a 29#include "util/debug.h"
e248de33
ACM
30#include "util/evlist.h"
31#include "util/evsel.h"
ef4b1a53 32#include "util/evswitch.h"
7c6a1c65 33#include "util/header.h"
94c744b6 34#include "util/session.h"
97b9d866 35#include "util/srcline.h"
45694aa7 36#include "util/tool.h"
53cb8bc2 37
4b6ab94e 38#include <subcmd/parse-options.h>
34b7b0f9 39#include <subcmd/exec-cmd.h>
53cb8bc2
IM
40#include "util/parse-events.h"
41
6baa0a5a 42#include "util/thread.h"
dd68ada2 43#include "util/sort.h"
3d1d07ec 44#include "util/hist.h"
f5fc1412 45#include "util/data.h"
68e94f4e 46#include "arch/common.h"
46690a80 47#include "util/time-utils.h"
520a2ebc 48#include "util/auxtrace.h"
58db1d6e 49#include "util/units.h"
fb71c86c 50#include "util/util.h" // perf_tip()
8520a98d 51#include "ui/ui.h"
171f7474 52#include "ui/progress.h"
6f7164fa 53#include "util/block-info.h"
520a2ebc 54
fc67297b 55#include <dlfcn.h>
a43783ae 56#include <errno.h>
fd20e811 57#include <inttypes.h>
1eae20c1 58#include <regex.h>
3052ba56 59#include <linux/ctype.h>
9607ad3a 60#include <signal.h>
5d67be97 61#include <linux/bitmap.h>
8520a98d 62#include <linux/string.h>
531d2410 63#include <linux/stringify.h>
2a1292cb 64#include <linux/time64.h>
7a8ef4c4
ACM
65#include <sys/types.h>
66#include <sys/stat.h>
67#include <unistd.h>
6439d7d1 68#include <linux/mman.h>
5d67be97 69
378ef0f5
IR
70#ifdef HAVE_LIBTRACEEVENT
71#include <traceevent/event-parse.h>
72#endif
73
28b21393 74struct report {
45694aa7 75 struct perf_tool tool;
d20deb64 76 struct perf_session *session;
ef4b1a53 77 struct evswitch evswitch;
3402ae0a
IR
78#ifdef HAVE_SLANG_SUPPORT
79 bool use_tui;
80#endif
557cc18e 81#ifdef HAVE_GTK2_SUPPORT
3402ae0a 82 bool use_gtk;
557cc18e 83#endif
3402ae0a 84 bool use_stdio;
fa372aae
ACM
85 bool show_full_info;
86 bool show_threads;
87 bool inverted_callchain;
f4f7e28d 88 bool mem_mode;
a4a4d0a7 89 bool stats_mode;
930f8b34 90 bool tasks_mode;
6439d7d1 91 bool mmaps_mode;
5cfe2c82
JO
92 bool header;
93 bool header_only;
98df858e 94 bool nonany_branch_mode;
57b5de46 95 bool group_set;
b1d1429b 96 bool stitch_lbr;
2e989f82 97 bool disable_order;
2775de0b 98 bool skip_empty;
91e95617 99 int max_stack;
fa372aae
ACM
100 struct perf_read_values show_threads_values;
101 const char *pretty_printing_style;
fa372aae 102 const char *cpu_list;
b14ffaca 103 const char *symbol_filter_str;
46690a80 104 const char *time_str;
0a3cc3ae
JY
105 struct perf_time_interval *ptime_range;
106 int range_size;
5b969bc7 107 int range_num;
064f1981 108 float min_percent;
58c311da 109 u64 nr_entries;
94786b67 110 u64 queue_size;
6f7164fa 111 u64 total_cycles;
21394d94 112 int socket_filter;
fa372aae 113 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
2d78b189 114 struct branch_type_stat brtype_stat;
ec6ae74f 115 bool symbol_ipc;
6f7164fa
JY
116 bool total_cycles_mode;
117 struct block_report *block_reports;
cca0cc76 118 int nr_block_reports;
d20deb64 119};
5d67be97 120
28b21393 121static int report__config(const char *var, const char *value, void *cb)
00c7e1f1 122{
94786b67
JO
123 struct report *rep = cb;
124
00c7e1f1
NK
125 if (!strcmp(var, "report.group")) {
126 symbol_conf.event_group = perf_config_bool(var, value);
127 return 0;
128 }
eec574e6 129 if (!strcmp(var, "report.percent-limit")) {
2665b452
NK
130 double pcnt = strtof(value, NULL);
131
132 rep->min_percent = pcnt;
133 callchain_param.min_percent = pcnt;
eec574e6
NK
134 return 0;
135 }
8d8e645c
NK
136 if (!strcmp(var, "report.children")) {
137 symbol_conf.cumulate_callchain = perf_config_bool(var, value);
138 return 0;
139 }
25ce4bb8
ACM
140 if (!strcmp(var, "report.queue-size"))
141 return perf_config_u64(&rep->queue_size, var, value);
142
fa1f4565
ACM
143 if (!strcmp(var, "report.sort_order")) {
144 default_sort_order = strdup(value);
8f08c363
IR
145 if (!default_sort_order) {
146 pr_err("Not enough memory for report.sort_order\n");
147 return -1;
148 }
fa1f4565
ACM
149 return 0;
150 }
00c7e1f1 151
8f08cf33
NK
152 if (!strcmp(var, "report.skip-empty")) {
153 rep->skip_empty = perf_config_bool(var, value);
154 return 0;
155 }
156
8f08c363 157 pr_debug("%s variable unknown, ignoring...", var);
b8cbb349 158 return 0;
00c7e1f1
NK
159}
160
9d3c02d7
NK
161static int hist_iter__report_callback(struct hist_entry_iter *iter,
162 struct addr_location *al, bool single,
163 void *arg)
164{
165 int err = 0;
166 struct report *rep = arg;
167 struct hist_entry *he = iter->he;
32dcd021 168 struct evsel *evsel = iter->evsel;
bab89f6a 169 struct perf_sample *sample = iter->sample;
9d3c02d7
NK
170 struct mem_info *mi;
171 struct branch_info *bi;
172
ec6ae74f 173 if (!ui__has_annotation() && !rep->symbol_ipc)
9d3c02d7
NK
174 return 0;
175
176 if (sort__mode == SORT_MODE__BRANCH) {
177 bi = he->branch_info;
e345f3bd 178 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
9d3c02d7
NK
179 if (err)
180 goto out;
181
e345f3bd 182 err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
9d3c02d7
NK
183
184 } else if (rep->mem_mode) {
185 mi = he->mem_info;
e345f3bd 186 err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
9d3c02d7
NK
187 if (err)
188 goto out;
189
e345f3bd 190 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7
NK
191
192 } else if (symbol_conf.cumulate_callchain) {
193 if (single)
e345f3bd 194 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7 195 } else {
e345f3bd 196 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7
NK
197 }
198
199out:
200 return err;
f4f7e28d
SE
201}
202
2d78b189
JY
203static int hist_iter__branch_callback(struct hist_entry_iter *iter,
204 struct addr_location *al __maybe_unused,
205 bool single __maybe_unused,
206 void *arg)
207{
208 struct hist_entry *he = iter->he;
209 struct report *rep = arg;
c3b10649 210 struct branch_info *bi = he->branch_info;
40c39e30 211 struct perf_sample *sample = iter->sample;
32dcd021 212 struct evsel *evsel = iter->evsel;
40c39e30
JY
213 int err;
214
c3b10649
JY
215 branch_type_count(&rep->brtype_stat, &bi->flags,
216 bi->from.addr, bi->to.addr);
217
ec6ae74f 218 if (!ui__has_annotation() && !rep->symbol_ipc)
40c39e30
JY
219 return 0;
220
e345f3bd 221 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
40c39e30
JY
222 if (err)
223 goto out;
224
e345f3bd 225 err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
40c39e30 226
40c39e30
JY
227out:
228 return err;
2d78b189
JY
229}
230
57b5de46 231static void setup_forced_leader(struct report *report,
63503dba 232 struct evlist *evlist)
57b5de46 233{
a26bb0ba 234 if (report->group_set)
64b4778b 235 evlist__force_leader(evlist);
57b5de46
JO
236}
237
89f1688a
JO
238static int process_feature_event(struct perf_session *session,
239 union perf_event *event)
57b5de46 240{
89f1688a 241 struct report *rep = container_of(session->tool, struct report, tool);
57b5de46
JO
242
243 if (event->feat.feat_id < HEADER_LAST_FEATURE)
89f1688a 244 return perf_event__process_feature(session, event);
57b5de46
JO
245
246 if (event->feat.feat_id != HEADER_LAST_FEATURE) {
1b8896fb 247 pr_err("failed: wrong feature ID: %" PRI_lu64 "\n",
57b5de46
JO
248 event->feat.feat_id);
249 return -1;
03de8656
NK
250 } else if (rep->header_only) {
251 session_done = 1;
57b5de46
JO
252 }
253
254 /*
92ead7ee
RB
255 * (feat_id = HEADER_LAST_FEATURE) is the end marker which
256 * means all features are received, now we can force the
57b5de46
JO
257 * group if needed.
258 */
259 setup_forced_leader(rep, session->evlist);
260 return 0;
261}
262
45694aa7 263static int process_sample_event(struct perf_tool *tool,
d20deb64 264 union perf_event *event,
8115d60c 265 struct perf_sample *sample,
32dcd021 266 struct evsel *evsel,
743eb868 267 struct machine *machine)
75051724 268{
28b21393 269 struct report *rep = container_of(tool, struct report, tool);
1ed091c4 270 struct addr_location al;
69bcb019 271 struct hist_entry_iter iter = {
063bd936
NK
272 .evsel = evsel,
273 .sample = sample,
b49a8fe5 274 .hide_unresolved = symbol_conf.hide_unresolved,
063bd936 275 .add_entry_cb = hist_iter__report_callback,
69bcb019 276 };
b91fc39f 277 int ret = 0;
180f95e2 278
5b969bc7
JY
279 if (perf_time__ranges_skip_sample(rep->ptime_range, rep->range_num,
280 sample->time)) {
46690a80 281 return 0;
5b969bc7 282 }
46690a80 283
ef4b1a53
ACM
284 if (evswitch__discard(&rep->evswitch, evsel))
285 return 0;
286
0dd5041c 287 addr_location__init(&al);
bb3eb566 288 if (machine__resolve(machine, &al, sample) < 0) {
a4210141
NK
289 pr_debug("problem processing %d event, skipping it.\n",
290 event->header.type);
0dd5041c
IR
291 ret = -1;
292 goto out_put;
75051724 293 }
e7fb08b1 294
b1d1429b 295 if (rep->stitch_lbr)
ee84a303 296 thread__set_lbr_stitch_enable(al.thread, true);
b1d1429b 297
b49a8fe5 298 if (symbol_conf.hide_unresolved && al.sym == NULL)
b91fc39f 299 goto out_put;
7bec7a91 300
fa372aae 301 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
b91fc39f 302 goto out_put;
5d67be97 303
f86225db
AH
304 if (sort__mode == SORT_MODE__BRANCH) {
305 /*
306 * A non-synthesized event might not have a branch stack if
307 * branch stacks have been synthesized (using itrace options).
308 */
309 if (!sample->branch_stack)
310 goto out_put;
2d78b189
JY
311
312 iter.add_entry_cb = hist_iter__branch_callback;
69bcb019 313 iter.ops = &hist_iter_branch;
f86225db 314 } else if (rep->mem_mode) {
69bcb019 315 iter.ops = &hist_iter_mem;
f86225db 316 } else if (symbol_conf.cumulate_callchain) {
7a13aa28 317 iter.ops = &hist_iter_cumulative;
f86225db 318 } else {
69bcb019 319 iter.ops = &hist_iter_normal;
f86225db 320 }
69bcb019
NK
321
322 if (al.map != NULL)
63df0e4b 323 map__dso(al.map)->hit = 1;
69bcb019 324
6f7164fa 325 if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
bdd1666b 326 hist__account_cycles(sample->branch_stack, &al, sample,
6f7164fa
JY
327 rep->nonany_branch_mode,
328 &rep->total_cycles);
bdd1666b
JY
329 }
330
063bd936 331 ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
69bcb019
NK
332 if (ret < 0)
333 pr_debug("problem adding hist entry, skipping event\n");
b91fc39f 334out_put:
0dd5041c 335 addr_location__exit(&al);
27a0dcb7 336 return ret;
75051724 337}
3502973d 338
45694aa7 339static int process_read_event(struct perf_tool *tool,
d20deb64 340 union perf_event *event,
1d037ca1 341 struct perf_sample *sample __maybe_unused,
32dcd021 342 struct evsel *evsel,
1d037ca1 343 struct machine *machine __maybe_unused)
e9ea2fde 344{
28b21393 345 struct report *rep = container_of(tool, struct report, tool);
743eb868 346
fa372aae 347 if (rep->show_threads) {
8ab2e96d 348 const char *name = evsel__name(evsel);
89973506 349 int err = perf_read_values_add_value(&rep->show_threads_values,
8d513270 350 event->read.pid, event->read.tid,
38fe0e01 351 evsel->core.idx,
8d513270
BG
352 name,
353 event->read.value);
89973506
ACM
354
355 if (err)
356 return err;
8d513270
BG
357 }
358
e9ea2fde
PZ
359 return 0;
360}
361
300aa941 362/* For pipe mode, sample_type is not currently set */
28b21393 363static int report__setup_sample_type(struct report *rep)
d80d338d 364{
c824c433 365 struct perf_session *session = rep->session;
b3c2cc2b 366 u64 sample_type = evlist__combined_sample_type(session->evlist);
8ceb41d7 367 bool is_pipe = perf_data__is_pipe(session->data);
ccb17cae 368 struct evsel *evsel;
d20deb64 369
d062ac16 370 if (session->itrace_synth_opts->callchain ||
1c5c25b3 371 session->itrace_synth_opts->add_callchain ||
d062ac16
AH
372 (!is_pipe &&
373 perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
374 !session->itrace_synth_opts->set))
375 sample_type |= PERF_SAMPLE_CALLCHAIN;
376
ec90e42c
AH
377 if (session->itrace_synth_opts->last_branch ||
378 session->itrace_synth_opts->add_last_branch)
c7eced63
AH
379 sample_type |= PERF_SAMPLE_BRANCH_STACK;
380
cc9784bd 381 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
de7e6a7c 382 if (perf_hpp_list.parent) {
3780f488 383 ui__error("Selected --sort parent, but no "
00894ce9
ACM
384 "callchain data. Did you call "
385 "'perf record' without -g?\n");
d549c769 386 return -EINVAL;
91b4eaea 387 }
b49a821e
JY
388 if (symbol_conf.use_callchain &&
389 !symbol_conf.show_branchflag_count) {
390 ui__error("Selected -g or --branch-history.\n"
391 "But no callchain or branch data.\n"
392 "Did you call 'perf record' without -g or -b?\n");
016e92fb 393 return -1;
91b4eaea 394 }
1cc83815 395 } else if (!callchain_param.enabled &&
fa372aae 396 callchain_param.mode != CHAIN_NONE &&
b9a63b9b 397 !symbol_conf.use_callchain) {
d599db3f 398 symbol_conf.use_callchain = true;
16537f13 399 if (callchain_register_param(&callchain_param) < 0) {
3780f488 400 ui__error("Can't register callchain params.\n");
d549c769 401 return -EINVAL;
b1a88349 402 }
f5970550
PZ
403 }
404
793aaaab
NK
405 if (symbol_conf.cumulate_callchain) {
406 /* Silently ignore if callchain is missing */
407 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
408 symbol_conf.cumulate_callchain = false;
409 perf_hpp__cancel_cumulate();
410 }
411 }
412
55369fc1 413 if (sort__mode == SORT_MODE__BRANCH) {
cc9784bd 414 if (!is_pipe &&
7f3be652 415 !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
3780f488
NK
416 ui__error("Selected -b but no branch data. "
417 "Did you call perf record without -b?\n");
b50311dc
RAV
418 return -1;
419 }
420 }
421
bb30acae 422 if (sort__mode == SORT_MODE__MEMORY) {
ccb17cae
LY
423 /*
424 * FIXUP: prior to kernel 5.18, Arm SPE missed to set
425 * PERF_SAMPLE_DATA_SRC bit in sample type. For backward
426 * compatibility, set the bit if it's an old perf data file.
427 */
428 evlist__for_each_entry(session->evlist, evsel) {
429 if (strstr(evsel->name, "arm_spe") &&
430 !(sample_type & PERF_SAMPLE_DATA_SRC)) {
431 evsel->core.attr.sample_type |= PERF_SAMPLE_DATA_SRC;
432 sample_type |= PERF_SAMPLE_DATA_SRC;
433 }
434 }
435
bb30acae
RB
436 if (!is_pipe && !(sample_type & PERF_SAMPLE_DATA_SRC)) {
437 ui__error("Selected --mem-mode but no mem data. "
438 "Did you call perf record without -d?\n");
439 return -1;
440 }
441 }
442
aa8db3e4 443 callchain_param_setup(sample_type, perf_env__arch(&rep->session->header.env));
98df858e 444
b1d1429b
KL
445 if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
446 ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
447 "Please apply --call-graph lbr when recording.\n");
448 rep->stitch_lbr = false;
449 }
450
98df858e 451 /* ??? handle more cases than just ANY? */
92c7d7cd 452 if (!(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY))
98df858e
AK
453 rep->nonany_branch_mode = true;
454
c3314a74 455#if !defined(HAVE_LIBUNWIND_SUPPORT) && !defined(HAVE_DWARF_SUPPORT)
800d3f56 456 if (dwarf_callchain_users) {
c3314a74
JY
457 ui__warning("Please install libunwind or libdw "
458 "development packages during the perf build.\n");
800d3f56
JY
459 }
460#endif
461
016e92fb
FW
462 return 0;
463}
6142f9ec 464
1d037ca1 465static void sig_handler(int sig __maybe_unused)
46656ac7
TZ
466{
467 session_done = 1;
468}
469
28b21393 470static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
c82ee828
ACM
471 const char *evname, FILE *fp)
472{
473 size_t ret;
474 char unit;
0f0abbac 475 unsigned long nr_samples = hists->stats.nr_samples;
c824c433 476 u64 nr_events = hists->stats.total_period;
32dcd021 477 struct evsel *evsel = hists_to_evsel(hists);
717e263f
NK
478 char buf[512];
479 size_t size = sizeof(buf);
84734b06 480 int socked_id = hists->socket_filter;
717e263f 481
27fafab5
NK
482 if (quiet)
483 return 0;
484
f2148330
NK
485 if (symbol_conf.filter_relative) {
486 nr_samples = hists->stats.nr_non_filtered_samples;
487 nr_events = hists->stats.total_non_filtered_period;
488 }
489
c754c382 490 if (evsel__is_group_event(evsel)) {
32dcd021 491 struct evsel *pos;
717e263f 492
347c751a 493 evsel__group_desc(evsel, buf, size);
717e263f
NK
494 evname = buf;
495
496 for_each_group_member(pos, evsel) {
4ea062ed
ACM
497 const struct hists *pos_hists = evsel__hists(pos);
498
f2148330 499 if (symbol_conf.filter_relative) {
4ea062ed
ACM
500 nr_samples += pos_hists->stats.nr_non_filtered_samples;
501 nr_events += pos_hists->stats.total_non_filtered_period;
f2148330 502 } else {
0f0abbac 503 nr_samples += pos_hists->stats.nr_samples;
4ea062ed 504 nr_events += pos_hists->stats.total_period;
f2148330 505 }
717e263f
NK
506 }
507 }
c82ee828 508
cc686280
AR
509 nr_samples = convert_unit(nr_samples, &unit);
510 ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
8ef278bb
JO
511 if (evname != NULL) {
512 ret += fprintf(fp, " of event%s '%s'",
5643b1a5 513 evsel->core.nr_members > 1 ? "s" : "", evname);
8ef278bb 514 }
cc686280 515
7425664b
JY
516 if (rep->time_str)
517 ret += fprintf(fp, " (time slices: %s)", rep->time_str);
518
11b6e548 519 if (symbol_conf.show_ref_callgraph && evname && strstr(evname, "call-graph=no")) {
9e207ddf
KL
520 ret += fprintf(fp, ", show reference callgraph");
521 }
522
f4f7e28d
SE
523 if (rep->mem_mode) {
524 ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
228f14f2 525 ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order);
f4f7e28d
SE
526 } else
527 ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
21394d94 528
84734b06
KL
529 if (socked_id > -1)
530 ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
21394d94 531
c82ee828
ACM
532 return ret + fprintf(fp, "\n#\n");
533}
534
f4bd0b4a 535static int evlist__tui_block_hists_browse(struct evlist *evlist, struct report *rep)
7fa46cbf
JY
536{
537 struct evsel *pos;
538 int i = 0, ret;
539
540 evlist__for_each_entry(evlist, pos) {
541 ret = report__browse_block_hists(&rep->block_reports[i++].hist,
848a5e50 542 rep->min_percent, pos,
22197fb2 543 &rep->session->header.env);
7fa46cbf
JY
544 if (ret != 0)
545 return ret;
546 }
547
548 return 0;
549}
550
f4bd0b4a 551static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, const char *help)
d67f088e 552{
32dcd021 553 struct evsel *pos;
6f7164fa 554 int i = 0;
d67f088e 555
27fafab5
NK
556 if (!quiet) {
557 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
558 evlist->stats.total_lost_samples);
559 }
560
e5cadb93 561 evlist__for_each_entry(evlist, pos) {
4ea062ed 562 struct hists *hists = evsel__hists(pos);
8ab2e96d 563 const char *evname = evsel__name(pos);
d67f088e 564
c754c382 565 if (symbol_conf.event_group && !evsel__is_group_leader(pos))
fc24d7c2
NK
566 continue;
567
2775de0b
NK
568 if (rep->skip_empty && !hists->stats.nr_samples)
569 continue;
570
28b21393 571 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
6f7164fa
JY
572
573 if (rep->total_cycles_mode) {
574 report__browse_block_hists(&rep->block_reports[i++].hist,
22197fb2 575 rep->min_percent, pos, NULL);
6f7164fa
JY
576 continue;
577 }
578
27fafab5 579 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
e9de7e2f
ACM
580 !(symbol_conf.use_callchain ||
581 symbol_conf.show_branchflag_count));
d67f088e 582 fprintf(stdout, "\n\n");
d67f088e
ACM
583 }
584
8b53dbef 585 if (!quiet)
d67f088e
ACM
586 fprintf(stdout, "#\n# (%s)\n#\n", help);
587
021162cf
NK
588 if (rep->show_threads) {
589 bool style = !strcmp(rep->pretty_printing_style, "raw");
590 perf_read_values_display(stdout, &rep->show_threads_values,
591 style);
592 perf_read_values_destroy(&rep->show_threads_values);
d67f088e
ACM
593 }
594
2d78b189
JY
595 if (sort__mode == SORT_MODE__BRANCH)
596 branch_type_stat_display(stdout, &rep->brtype_stat);
597
d67f088e
ACM
598 return 0;
599}
600
fad2918e
ACM
601static void report__warn_kptr_restrict(const struct report *rep)
602{
a5e813c6 603 struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
f6fcc143 604 struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
fad2918e 605
78e1bc25 606 if (evlist__exclude_kernel(rep->session->evlist))
9c39ed90
ACM
607 return;
608
fad2918e 609 if (kernel_map == NULL ||
63df0e4b 610 (map__dso(kernel_map)->hit &&
fad2918e
ACM
611 (kernel_kmap->ref_reloc_sym == NULL ||
612 kernel_kmap->ref_reloc_sym->addr == 0))) {
613 const char *desc =
614 "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
615 "can't be resolved.";
616
e94b861a
ACM
617 if (kernel_map && map__has_symbols(kernel_map)) {
618 desc = "If some relocation was applied (e.g. "
619 "kexec) symbols may be misresolved.";
fad2918e
ACM
620 }
621
622 ui__warning(
623"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
624"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
625"Samples in kernel modules can't be resolved as well.\n\n",
626 desc);
627 }
628}
629
8362951b
ACM
630static int report__gtk_browse_hists(struct report *rep, const char *help)
631{
63503dba 632 int (*hist_browser)(struct evlist *evlist, const char *help,
8362951b
ACM
633 struct hist_browser_timer *timer, float min_pcnt);
634
f4bd0b4a 635 hist_browser = dlsym(perf_gtk_handle, "evlist__gtk_browse_hists");
8362951b
ACM
636
637 if (hist_browser == NULL) {
638 ui__error("GTK browser not found!\n");
639 return -1;
640 }
641
642 return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
643}
644
645static int report__browse_hists(struct report *rep)
646{
647 int ret;
648 struct perf_session *session = rep->session;
63503dba 649 struct evlist *evlist = session->evlist;
d9fc7061 650 char *help = NULL, *path = NULL;
34b7b0f9 651
d9fc7061
IR
652 path = system_path(TIPDIR);
653 if (perf_tip(&help, path) || help == NULL) {
34b7b0f9 654 /* fallback for people who don't install perf ;-) */
d9fc7061
IR
655 free(path);
656 path = system_path(DOCDIR);
657 if (perf_tip(&help, path) || help == NULL)
658 help = strdup("Cannot load tips.txt file, please install perf!");
34b7b0f9 659 }
d9fc7061 660 free(path);
8362951b
ACM
661
662 switch (use_browser) {
663 case 1:
7fa46cbf 664 if (rep->total_cycles_mode) {
f4bd0b4a 665 ret = evlist__tui_block_hists_browse(evlist, rep);
7fa46cbf
JY
666 break;
667 }
668
f4bd0b4a 669 ret = evlist__tui_browse_hists(evlist, help, NULL, rep->min_percent,
22197fb2 670 &session->header.env, true);
8362951b
ACM
671 /*
672 * Usually "ret" is the last pressed key, and we only
673 * care if the key notifies us to switch data file.
674 */
5e3b810a 675 if (ret != K_SWITCH_INPUT_DATA && ret != K_RELOAD)
8362951b
ACM
676 ret = 0;
677 break;
678 case 2:
679 ret = report__gtk_browse_hists(rep, help);
680 break;
681 default:
f4bd0b4a 682 ret = evlist__tty_browse_hists(evlist, rep, help);
8362951b
ACM
683 break;
684 }
d9fc7061 685 free(help);
8362951b
ACM
686 return ret;
687}
688
5b2ea6f2 689static int report__collapse_hists(struct report *rep)
f6d8b057 690{
a6e4a4a1
NK
691 struct perf_session *session = rep->session;
692 struct evlist *evlist = session->evlist;
f6d8b057 693 struct ui_progress prog;
32dcd021 694 struct evsel *pos;
5b2ea6f2 695 int ret = 0;
f6d8b057 696
a6e4a4a1
NK
697 /*
698 * The pipe data needs to setup hierarchy hpp formats now, because it
699 * cannot know about evsels in the data before reading the data. The
700 * normal file data saves the event (attribute) info in the header
701 * section, but pipe does not have the luxury.
702 */
703 if (perf_data__is_pipe(session->data)) {
704 if (perf_hpp__setup_hists_formats(&perf_hpp_list, evlist) < 0) {
0e0f03d7 705 ui__error("Failed to setup hierarchy output formats\n");
a6e4a4a1
NK
706 return -1;
707 }
708 }
709
58c311da 710 ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
f6d8b057 711
e5cadb93 712 evlist__for_each_entry(rep->session->evlist, pos) {
4ea062ed 713 struct hists *hists = evsel__hists(pos);
f6d8b057 714
38fe0e01 715 if (pos->core.idx == 0)
f6d8b057
ACM
716 hists->symbol_filter_str = rep->symbol_filter_str;
717
21394d94
KL
718 hists->socket_filter = rep->socket_filter;
719
5b2ea6f2
NK
720 ret = hists__collapse_resort(hists, &prog);
721 if (ret < 0)
722 break;
f6d8b057
ACM
723
724 /* Non-group events are considered as leader */
c754c382 725 if (symbol_conf.event_group && !evsel__is_group_leader(pos)) {
fba7c866 726 struct hists *leader_hists = evsel__hists(evsel__leader(pos));
f6d8b057
ACM
727
728 hists__match(leader_hists, hists);
729 hists__link(leader_hists, hists);
730 }
731 }
732
733 ui_progress__finish();
5b2ea6f2 734 return ret;
f6d8b057
ACM
735}
736
dbd2a1d5
JO
737static int hists__resort_cb(struct hist_entry *he, void *arg)
738{
739 struct report *rep = arg;
740 struct symbol *sym = he->ms.sym;
741
742 if (rep->symbol_ipc && sym && !sym->annotate2) {
32dcd021 743 struct evsel *evsel = hists_to_evsel(he->hists);
dbd2a1d5 744
41fd3cac 745 symbol__annotate2(&he->ms, evsel, NULL);
dbd2a1d5
JO
746 }
747
748 return 0;
749}
750
740b97f9
NK
751static void report__output_resort(struct report *rep)
752{
753 struct ui_progress prog;
32dcd021 754 struct evsel *pos;
740b97f9
NK
755
756 ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
757
dbd2a1d5 758 evlist__for_each_entry(rep->session->evlist, pos) {
10c513f7 759 evsel__output_resort_cb(pos, &prog, hists__resort_cb, rep);
dbd2a1d5 760 }
740b97f9
NK
761
762 ui_progress__finish();
763}
764
55f75444
NK
765static int count_sample_event(struct perf_tool *tool __maybe_unused,
766 union perf_event *event __maybe_unused,
767 struct perf_sample *sample __maybe_unused,
768 struct evsel *evsel,
769 struct machine *machine __maybe_unused)
770{
771 struct hists *hists = evsel__hists(evsel);
772
773 hists__inc_nr_events(hists);
774 return 0;
775}
776
d7ba22d4
NK
777static int count_lost_samples_event(struct perf_tool *tool,
778 union perf_event *event,
779 struct perf_sample *sample,
780 struct machine *machine __maybe_unused)
781{
782 struct report *rep = container_of(tool, struct report, tool);
783 struct evsel *evsel;
784
785 evsel = evlist__id2evsel(rep->session->evlist, sample->id);
786 if (evsel) {
787 hists__inc_nr_lost_samples(evsel__hists(evsel),
788 event->lost_samples.lost);
789 }
790 return 0;
791}
792
892ba7f1
NK
793static int process_attr(struct perf_tool *tool __maybe_unused,
794 union perf_event *event,
795 struct evlist **pevlist);
796
a4a4d0a7
JO
797static void stats_setup(struct report *rep)
798{
799 memset(&rep->tool, 0, sizeof(rep->tool));
892ba7f1 800 rep->tool.attr = process_attr;
55f75444 801 rep->tool.sample = count_sample_event;
d7ba22d4 802 rep->tool.lost_samples = count_lost_samples_event;
a4a4d0a7
JO
803 rep->tool.no_warn = true;
804}
805
806static int stats_print(struct report *rep)
807{
808 struct perf_session *session = rep->session;
809
2775de0b
NK
810 perf_session__fprintf_nr_events(session, stdout, rep->skip_empty);
811 evlist__fprintf_nr_events(session->evlist, stdout, rep->skip_empty);
a4a4d0a7
JO
812 return 0;
813}
814
930f8b34
JO
815static void tasks_setup(struct report *rep)
816{
817 memset(&rep->tool, 0, sizeof(rep->tool));
8614ada0 818 rep->tool.ordered_events = true;
6439d7d1
ACM
819 if (rep->mmaps_mode) {
820 rep->tool.mmap = perf_event__process_mmap;
821 rep->tool.mmap2 = perf_event__process_mmap2;
822 }
892ba7f1 823 rep->tool.attr = process_attr;
930f8b34
JO
824 rep->tool.comm = perf_event__process_comm;
825 rep->tool.exit = perf_event__process_exit;
826 rep->tool.fork = perf_event__process_fork;
827 rep->tool.no_warn = true;
828}
829
830struct task {
831 struct thread *thread;
832 struct list_head list;
833 struct list_head children;
834};
835
836static struct task *tasks_list(struct task *task, struct machine *machine)
837{
838 struct thread *parent_thread, *thread = task->thread;
839 struct task *parent_task;
840
841 /* Already listed. */
842 if (!list_empty(&task->list))
843 return NULL;
844
845 /* Last one in the chain. */
ee84a303 846 if (thread__ppid(thread) == -1)
930f8b34
JO
847 return task;
848
ee84a303 849 parent_thread = machine__find_thread(machine, -1, thread__ppid(thread));
930f8b34
JO
850 if (!parent_thread)
851 return ERR_PTR(-ENOENT);
852
853 parent_task = thread__priv(parent_thread);
2c9f7bd7 854 thread__put(parent_thread);
930f8b34
JO
855 list_add_tail(&task->list, &parent_task->children);
856 return tasks_list(parent_task, machine);
857}
858
6439d7d1
ACM
859static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
860{
861 size_t printed = 0;
ff583dc4
IR
862 struct map_rb_node *rb_node;
863
864 maps__for_each_entry(maps, rb_node) {
865 struct map *map = rb_node->map;
63df0e4b 866 const struct dso *dso = map__dso(map);
ddee3f2b 867 u32 prot = map__prot(map);
6439d7d1
ACM
868
869 printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
e5116f46 870 indent, "", map__start(map), map__end(map),
ddee3f2b
IR
871 prot & PROT_READ ? 'r' : '-',
872 prot & PROT_WRITE ? 'w' : '-',
873 prot & PROT_EXEC ? 'x' : '-',
874 map__flags(map) ? 's' : 'p',
2a6e5e8a 875 map__pgoff(map),
63df0e4b 876 dso->id.ino, dso->name);
6439d7d1
ACM
877 }
878
879 return printed;
880}
881
930f8b34
JO
882static void task__print_level(struct task *task, FILE *fp, int level)
883{
884 struct thread *thread = task->thread;
885 struct task *child;
6439d7d1 886 int comm_indent = fprintf(fp, " %8d %8d %8d |%*s",
ee84a303
IR
887 thread__pid(thread), thread__tid(thread),
888 thread__ppid(thread), level, "");
6439d7d1
ACM
889
890 fprintf(fp, "%s\n", thread__comm_str(thread));
930f8b34 891
ee84a303 892 maps__fprintf_task(thread__maps(thread), comm_indent, fp);
930f8b34
JO
893
894 if (!list_empty(&task->children)) {
895 list_for_each_entry(child, &task->children, list)
896 task__print_level(child, fp, level + 1);
897 }
898}
899
900static int tasks_print(struct report *rep, FILE *fp)
901{
902 struct perf_session *session = rep->session;
903 struct machine *machine = &session->machines.host;
904 struct task *tasks, *task;
905 unsigned int nr = 0, itask = 0, i;
906 struct rb_node *nd;
907 LIST_HEAD(list);
908
909 /*
910 * No locking needed while accessing machine->threads,
911 * because --tasks is single threaded command.
912 */
913
914 /* Count all the threads. */
915 for (i = 0; i < THREADS__TABLE_SIZE; i++)
916 nr += machine->threads[i].nr;
917
918 tasks = malloc(sizeof(*tasks) * nr);
919 if (!tasks)
920 return -ENOMEM;
921
922 for (i = 0; i < THREADS__TABLE_SIZE; i++) {
923 struct threads *threads = &machine->threads[i];
924
f3acb3a8
DB
925 for (nd = rb_first_cached(&threads->entries); nd;
926 nd = rb_next(nd)) {
930f8b34
JO
927 task = tasks + itask++;
928
7ee227f6 929 task->thread = rb_entry(nd, struct thread_rb_node, rb_node)->thread;
930f8b34
JO
930 INIT_LIST_HEAD(&task->children);
931 INIT_LIST_HEAD(&task->list);
932 thread__set_priv(task->thread, task);
933 }
934 }
935
936 /*
937 * Iterate every task down to the unprocessed parent
938 * and link all in task children list. Task with no
939 * parent is added into 'list'.
940 */
941 for (itask = 0; itask < nr; itask++) {
942 task = tasks + itask;
943
944 if (!list_empty(&task->list))
945 continue;
946
947 task = tasks_list(task, machine);
948 if (IS_ERR(task)) {
949 pr_err("Error: failed to process tasks\n");
950 free(tasks);
951 return PTR_ERR(task);
952 }
953
954 if (task)
955 list_add_tail(&task->list, &list);
956 }
957
958 fprintf(fp, "# %8s %8s %8s %s\n", "pid", "tid", "ppid", "comm");
959
960 list_for_each_entry(task, &list, list)
961 task__print_level(task, fp, 0);
962
963 free(tasks);
964 return 0;
965}
966
28b21393 967static int __cmd_report(struct report *rep)
016e92fb 968{
f6d8b057 969 int ret;
993ac88d 970 struct perf_session *session = rep->session;
32dcd021 971 struct evsel *pos;
8ceb41d7 972 struct perf_data *data = session->data;
8fa66bdc 973
46656ac7
TZ
974 signal(SIGINT, sig_handler);
975
fa372aae
ACM
976 if (rep->cpu_list) {
977 ret = perf_session__cpu_bitmap(session, rep->cpu_list,
978 rep->cpu_bitmap);
25b1606b
NK
979 if (ret) {
980 ui__error("failed to set cpu bitmap\n");
d4ae0a6f 981 return ret;
25b1606b 982 }
644e0840 983 session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
5d67be97
AB
984 }
985
89973506
ACM
986 if (rep->show_threads) {
987 ret = perf_read_values_init(&rep->show_threads_values);
988 if (ret)
989 return ret;
990 }
f5970550 991
28b21393 992 ret = report__setup_sample_type(rep);
25b1606b
NK
993 if (ret) {
994 /* report__setup_sample_type() already showed error message */
d4ae0a6f 995 return ret;
25b1606b 996 }
d549c769 997
a4a4d0a7
JO
998 if (rep->stats_mode)
999 stats_setup(rep);
1000
930f8b34
JO
1001 if (rep->tasks_mode)
1002 tasks_setup(rep);
1003
b7b61cbe 1004 ret = perf_session__process_events(session);
25b1606b
NK
1005 if (ret) {
1006 ui__error("failed to process sample\n");
d4ae0a6f 1007 return ret;
25b1606b 1008 }
97b07b69 1009
d5a8bd0f
JY
1010 evlist__check_mem_load_aux(session->evlist);
1011
a4a4d0a7
JO
1012 if (rep->stats_mode)
1013 return stats_print(rep);
1014
930f8b34
JO
1015 if (rep->tasks_mode)
1016 return tasks_print(rep, stdout);
1017
fad2918e 1018 report__warn_kptr_restrict(rep);
ec80fde7 1019
e5cadb93 1020 evlist__for_each_entry(session->evlist, pos)
590cd344
NK
1021 rep->nr_entries += evsel__hists(pos)->nr_entries;
1022
150e465a
NK
1023 if (use_browser == 0) {
1024 if (verbose > 3)
1025 perf_session__fprintf(session, stdout);
9ac99545 1026
150e465a
NK
1027 if (verbose > 2)
1028 perf_session__fprintf_dsos(session, stdout);
16f762a2 1029
150e465a 1030 if (dump_trace) {
2775de0b
NK
1031 perf_session__fprintf_nr_events(session, stdout,
1032 rep->skip_empty);
1033 evlist__fprintf_nr_events(session->evlist, stdout,
1034 rep->skip_empty);
150e465a
NK
1035 return 0;
1036 }
71ad0f5e
JO
1037 }
1038
5b2ea6f2
NK
1039 ret = report__collapse_hists(rep);
1040 if (ret) {
1041 ui__error("failed to process hist entry\n");
1042 return ret;
1043 }
e248de33 1044
33e940a2
ACM
1045 if (session_done())
1046 return 0;
1047
740b97f9
NK
1048 /*
1049 * recalculate number of entries after collapsing since it
1050 * might be changed during the collapse phase.
1051 */
1052 rep->nr_entries = 0;
e5cadb93 1053 evlist__for_each_entry(session->evlist, pos)
740b97f9
NK
1054 rep->nr_entries += evsel__hists(pos)->nr_entries;
1055
58c311da 1056 if (rep->nr_entries == 0) {
2d4f2799 1057 ui__error("The %s data has no samples!\n", data->path);
d4ae0a6f 1058 return 0;
cbbc79a5
EM
1059 }
1060
740b97f9 1061 report__output_resort(rep);
6e1f601a 1062
6f7164fa 1063 if (rep->total_cycles_mode) {
cca0cc76
JY
1064 int block_hpps[6] = {
1065 PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
1066 PERF_HPP_REPORT__BLOCK_LBR_CYCLES,
1067 PERF_HPP_REPORT__BLOCK_CYCLES_PCT,
1068 PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
1069 PERF_HPP_REPORT__BLOCK_RANGE,
1070 PERF_HPP_REPORT__BLOCK_DSO,
1071 };
1072
6f7164fa 1073 rep->block_reports = block_info__create_report(session->evlist,
cca0cc76
JY
1074 rep->total_cycles,
1075 block_hpps, 6,
1076 &rep->nr_block_reports);
6f7164fa
JY
1077 if (!rep->block_reports)
1078 return -1;
1079 }
1080
8362951b 1081 return report__browse_hists(rep);
8fa66bdc
ACM
1082}
1083
4eb3e478 1084static int
cff6bb46 1085report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
4eb3e478 1086{
1cc83815 1087 struct callchain_param *callchain = opt->value;
c20ab37e 1088
1cc83815 1089 callchain->enabled = !unset;
b9a63b9b
ACM
1090 /*
1091 * --no-call-graph
1092 */
1093 if (unset) {
1cc83815
ACM
1094 symbol_conf.use_callchain = false;
1095 callchain->mode = CHAIN_NONE;
b9a63b9b
ACM
1096 return 0;
1097 }
1098
cff6bb46 1099 return parse_callchain_report_opt(arg);
4eb3e478
FW
1100}
1101
2a1292cb
AK
1102static int
1103parse_time_quantum(const struct option *opt, const char *arg,
1104 int unset __maybe_unused)
1105{
1106 unsigned long *time_q = opt->value;
1107 char *end;
1108
1109 *time_q = strtoul(arg, &end, 0);
1110 if (end == arg)
1111 goto parse_err;
1112 if (*time_q == 0) {
1113 pr_err("time quantum cannot be 0");
1114 return -1;
1115 }
526bbbdd 1116 end = skip_spaces(end);
2a1292cb
AK
1117 if (*end == 0)
1118 return 0;
1119 if (!strcmp(end, "s")) {
1120 *time_q *= NSEC_PER_SEC;
1121 return 0;
1122 }
1123 if (!strcmp(end, "ms")) {
1124 *time_q *= NSEC_PER_MSEC;
1125 return 0;
1126 }
1127 if (!strcmp(end, "us")) {
1128 *time_q *= NSEC_PER_USEC;
1129 return 0;
1130 }
1131 if (!strcmp(end, "ns"))
1132 return 0;
1133parse_err:
1134 pr_err("Cannot parse time quantum `%s'\n", arg);
1135 return -1;
1136}
1137
b21484f1
GP
1138int
1139report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
1140 const char *arg, int unset __maybe_unused)
1141{
1142 if (arg) {
1143 int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
1144 if (err) {
1145 char buf[BUFSIZ];
1146 regerror(err, &ignore_callees_regex, buf, sizeof(buf));
1147 pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
1148 return -1;
1149 }
1150 have_ignore_callees = 1;
1151 }
1152
1153 return 0;
1154}
1155
993ac88d 1156static int
7e6a7998 1157parse_branch_mode(const struct option *opt,
1d037ca1 1158 const char *str __maybe_unused, int unset)
993ac88d 1159{
55369fc1
NK
1160 int *branch_mode = opt->value;
1161
1162 *branch_mode = !unset;
993ac88d
SE
1163 return 0;
1164}
1165
064f1981
NK
1166static int
1167parse_percent_limit(const struct option *opt, const char *str,
1168 int unset __maybe_unused)
1169{
28b21393 1170 struct report *rep = opt->value;
2665b452 1171 double pcnt = strtof(str, NULL);
064f1981 1172
2665b452
NK
1173 rep->min_percent = pcnt;
1174 callchain_param.min_percent = pcnt;
064f1981
NK
1175 return 0;
1176}
1177
0d71a2b2
JO
1178static int process_attr(struct perf_tool *tool __maybe_unused,
1179 union perf_event *event,
1180 struct evlist **pevlist)
1181{
1182 u64 sample_type;
1183 int err;
1184
1185 err = perf_event__process_attr(tool, event, pevlist);
1186 if (err)
1187 return err;
1188
1189 /*
1190 * Check if we need to enable callchains based
1191 * on events sample_type.
1192 */
b3c2cc2b 1193 sample_type = evlist__combined_sample_type(*pevlist);
aa8db3e4 1194 callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));
0d71a2b2
JO
1195 return 0;
1196}
1197
b0ad8ea6 1198int cmd_report(int argc, const char **argv)
d20deb64 1199{
993ac88d 1200 struct perf_session *session;
520a2ebc 1201 struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
efad1415 1202 struct stat st;
993ac88d 1203 bool has_br_stack = false;
55369fc1 1204 int branch_mode = -1;
0feba17b 1205 int last_key = 0;
fa94c36c 1206 bool branch_call_mode = false;
9d0199cd 1207#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent"
49b8e2be
RV
1208 static const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
1209 CALLCHAIN_REPORT_HELP
1210 "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
76a26549 1211 char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
d20deb64 1212 const char * const report_usage[] = {
fb2baceb 1213 "perf report [<options>]",
d20deb64
ACM
1214 NULL
1215 };
28b21393 1216 struct report report = {
45694aa7 1217 .tool = {
d20deb64
ACM
1218 .sample = process_sample_event,
1219 .mmap = perf_event__process_mmap,
5c5e854b 1220 .mmap2 = perf_event__process_mmap2,
d20deb64 1221 .comm = perf_event__process_comm,
f3b3614a 1222 .namespaces = perf_event__process_namespaces,
ba78c1c5 1223 .cgroup = perf_event__process_cgroup,
f62d3f0f
ACM
1224 .exit = perf_event__process_exit,
1225 .fork = perf_event__process_fork,
d20deb64
ACM
1226 .lost = perf_event__process_lost,
1227 .read = process_read_event,
0d71a2b2 1228 .attr = process_attr,
378ef0f5 1229#ifdef HAVE_LIBTRACEEVENT
d20deb64 1230 .tracing_data = perf_event__process_tracing_data,
378ef0f5 1231#endif
d20deb64 1232 .build_id = perf_event__process_build_id,
520a2ebc
AH
1233 .id_index = perf_event__process_id_index,
1234 .auxtrace_info = perf_event__process_auxtrace_info,
1235 .auxtrace = perf_event__process_auxtrace,
4ab8455f 1236 .event_update = perf_event__process_event_update,
57b5de46 1237 .feature = process_feature_event,
0a8cb85c 1238 .ordered_events = true,
d20deb64
ACM
1239 .ordering_requires_timestamps = true,
1240 },
fe176085 1241 .max_stack = PERF_MAX_STACK_DEPTH,
d20deb64 1242 .pretty_printing_style = "normal",
21394d94 1243 .socket_filter = -1,
8f08cf33 1244 .skip_empty = true,
d20deb64 1245 };
a37338aa
RM
1246 char *sort_order_help = sort_help("sort by key(s):");
1247 char *field_order_help = sort_help("output field(s): overhead period sample ");
57594454 1248 const char *disassembler_style = NULL, *objdump_path = NULL, *addr2line_path = NULL;
d20deb64 1249 const struct option options[] = {
70cb4e96 1250 OPT_STRING('i', "input", &input_name, "file",
53cb8bc2 1251 "input file name"),
c0555642 1252 OPT_INCR('v', "verbose", &verbose,
815e777f 1253 "be more verbose (show symbol address, etc)"),
a527c2c1 1254 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"),
97b07b69
IM
1255 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1256 "dump raw trace in ASCII"),
a4a4d0a7 1257 OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"),
930f8b34 1258 OPT_BOOLEAN(0, "tasks", &report.tasks_mode, "Display recorded tasks"),
6439d7d1 1259 OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
b32d133a
ACM
1260 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1261 "file", "vmlinux pathname"),
91340c51
ACM
1262 OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
1263 "don't load vmlinux even if found"),
b226a5a7
DA
1264 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1265 "file", "kallsyms pathname"),
2059fc7a 1266 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
b32d133a 1267 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
42976487 1268 "load module symbols - WARNING: use only with -k and LIVE kernel"),
d599db3f 1269 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
e3d7e183 1270 "Show a column with the number of samples"),
fa372aae 1271 OPT_BOOLEAN('T', "threads", &report.show_threads,
8d513270 1272 "Show per-thread event counters"),
fa372aae 1273 OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
9f866697 1274 "pretty printing style key: normal raw"),
3402ae0a 1275#ifdef HAVE_SLANG_SUPPORT
fa372aae 1276 OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
3402ae0a 1277#endif
557cc18e 1278#ifdef HAVE_GTK2_SUPPORT
c31a9457 1279 OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
557cc18e 1280#endif
fa372aae
ACM
1281 OPT_BOOLEAN(0, "stdio", &report.use_stdio,
1282 "Use the stdio interface"),
5cfe2c82
JO
1283 OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
1284 OPT_BOOLEAN(0, "header-only", &report.header_only,
1285 "Show only data header."),
63299f05 1286 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
a37338aa 1287 sort_order_help),
a7d945bc 1288 OPT_STRING('F', "fields", &field_order, "key[,keys...]",
a37338aa 1289 field_order_help),
b272a59d 1290 OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
a1645ce1 1291 "Show sample percentage for different cpu modes"),
b272a59d
NK
1292 OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
1293 "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
b25bcf2f
IM
1294 OPT_STRING('p', "parent", &parent_pattern, "regex",
1295 "regex filter to identify parent, see: '--sort parent'"),
d599db3f 1296 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
b8e6d829 1297 "Only display entries with parent-match"),
1cc83815 1298 OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
f2af0086 1299 "print_type,threshold[,print_limit],order,sort_key[,branch],value",
21cf6284
NK
1300 report_callchain_help, &report_parse_callchain_opt,
1301 callchain_default_opt),
793aaaab 1302 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
aa9d1f83
AK
1303 "Accumulate callchains of children and show total overhead as well. "
1304 "Enabled by default, use --no-children to disable."),
91e95617
WL
1305 OPT_INTEGER(0, "max-stack", &report.max_stack,
1306 "Set the maximum stack depth when parsing the callchain, "
1307 "anything beyond the specified depth will be ignored. "
4cb93446 1308 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
fa372aae
ACM
1309 OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
1310 "alias for inverted call graph"),
b21484f1
GP
1311 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
1312 "ignore callees of these functions in call graphs",
1313 report_parse_ignore_callees_opt),
655000e7 1314 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
25903407 1315 "only consider symbols in these dsos"),
c8e66720 1316 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
cc8b88b1 1317 "only consider symbols in these comms"),
e03eaa40
DA
1318 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
1319 "only consider symbols in these pids"),
1320 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
1321 "only consider symbols in these tids"),
655000e7 1322 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
7bec7a91 1323 "only consider these symbols"),
b14ffaca
NK
1324 OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
1325 "only show symbols that (partially) match with this filter"),
655000e7 1326 OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
52d422de
ACM
1327 "width[,width...]",
1328 "don't try to adjust column width, use these fixed values"),
0c8c2077 1329 OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
52d422de
ACM
1330 "separator for columns, no spaces will be added between "
1331 "columns '.' is reserved."),
b49a8fe5 1332 OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
71289be7 1333 "Only display entries resolved to a symbol"),
a7066709
HK
1334 OPT_CALLBACK(0, "symfs", NULL, "directory",
1335 "Look for files with symbols relative to this directory",
1336 symbol__config_symfs),
c8e66720 1337 OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
fa372aae
ACM
1338 "list of cpus to profile"),
1339 OPT_BOOLEAN('I', "show-info", &report.show_full_info,
fbe96f29 1340 "Display extended information about perf.data file"),
14953f03 1341 OPT_BOOLEAN(0, "source", &annotate_opts.annotate_src,
64c6f0c7 1342 "Interleave source code with assembly code (default)"),
14953f03 1343 OPT_BOOLEAN(0, "asm-raw", &annotate_opts.show_asm_raw,
64c6f0c7 1344 "Display raw encoding of assembly instructions (default)"),
56d9117c 1345 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
f69b64f7 1346 "Specify disassembler style (e.g. -M intel for intel syntax)"),
14953f03 1347 OPT_STRING(0, "prefix", &annotate_opts.prefix, "prefix",
3b0b16bf 1348 "Add prefix to source file path names in programs (with --prefix-strip)"),
14953f03 1349 OPT_STRING(0, "prefix-strip", &annotate_opts.prefix_strip, "N",
3b0b16bf 1350 "Strip first N entries of source file path name in programs (with --prefix)"),
3f2728bd
ACM
1351 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
1352 "Show a column with the sum of periods"),
57b5de46 1353 OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
01d14f16 1354 "Show event group information together"),
429a5f9d
JY
1355 OPT_INTEGER(0, "group-sort-idx", &symbol_conf.group_sort_idx,
1356 "Sort the output by the event at the index n in group. "
1357 "If n is invalid, sort by the first event. "
1358 "WARNING: should be used on grouped events."),
55369fc1 1359 OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
fa94c36c
AK
1360 "use branch records for per branch histogram filling",
1361 parse_branch_mode),
1362 OPT_BOOLEAN(0, "branch-history", &branch_call_mode,
1363 "add last branch records to call history"),
56d9117c 1364 OPT_STRING(0, "objdump", &objdump_path, "path",
7a4ec938 1365 "objdump binary to use for disassembly and annotations"),
57594454
IR
1366 OPT_STRING(0, "addr2line", &addr2line_path, "path",
1367 "addr2line binary to use for line numbers"),
328ccdac
NK
1368 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
1369 "Disable symbol demangling"),
763122ad
AK
1370 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1371 "Enable kernel symbol demangling"),
f4f7e28d 1372 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
4968ac8f
AK
1373 OPT_INTEGER(0, "samples", &symbol_conf.res_sample,
1374 "Number of samples to save per histogram entry for individual browsing"),
064f1981
NK
1375 OPT_CALLBACK(0, "percent-limit", &report, "percent",
1376 "Don't show entries under that percent", parse_percent_limit),
f2148330 1377 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
33db4568 1378 "how to display percentage of filtered entries", parse_filter_percentage),
520a2ebc 1379 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
c12e039d 1380 "Instruction Tracing options\n" ITRACE_HELP,
520a2ebc 1381 itrace_parse_synth_opts),
a9710ba0
AK
1382 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
1383 "Show full source file name path for source lines"),
9e207ddf
KL
1384 OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
1385 "Show callgraph from reference event"),
b1d1429b
KL
1386 OPT_BOOLEAN(0, "stitch-lbr", &report.stitch_lbr,
1387 "Enable LBR callgraph stitching approach"),
21394d94
KL
1388 OPT_INTEGER(0, "socket-filter", &report.socket_filter,
1389 "only show processor socket that match with this filter"),
053a3989
NK
1390 OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace,
1391 "Show raw trace event output (do not use print fmt or plugins)"),
4251446d
NK
1392 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1393 "Show entries in a hierarchy"),
175b968b
ACM
1394 OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
1395 "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
1396 stdio__config_color, "always"),
46690a80
DA
1397 OPT_STRING(0, "time", &report.time_str, "str",
1398 "Time span of interest (start,stop)"),
f3a60646
JY
1399 OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
1400 "Show inline function"),
14953f03 1401 OPT_CALLBACK(0, "percent-type", &annotate_opts, "local-period",
e6902d1b
JO
1402 "Set percent type local/global-period/hits",
1403 annotate_parse_percent_type),
52bab886 1404 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
2a1292cb
AK
1405 OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)",
1406 "Set time quantum for time sort key (default 100ms)",
1407 parse_time_quantum),
ef4b1a53 1408 OPTS_EVSWITCH(&report.evswitch),
6f7164fa
JY
1409 OPT_BOOLEAN(0, "total-cycles", &report.total_cycles_mode,
1410 "Sort all blocks by 'Sampled Cycles%'"),
2e989f82
JY
1411 OPT_BOOLEAN(0, "disable-order", &report.disable_order,
1412 "Disable raw trace ordering"),
2775de0b
NK
1413 OPT_BOOLEAN(0, "skip-empty", &report.skip_empty,
1414 "Do not display empty (or dummy) events in the output"),
53cb8bc2 1415 OPT_END()
d20deb64 1416 };
8ceb41d7 1417 struct perf_data data = {
f5fc1412
JO
1418 .mode = PERF_DATA_MODE_READ,
1419 };
a635fc51 1420 int ret = hists__init();
ec6ae74f 1421 char sort_tmp[128];
a635fc51
ACM
1422
1423 if (ret < 0)
a37338aa 1424 goto exit;
53cb8bc2 1425
9ffa6c75
IR
1426 /*
1427 * tasks_mode require access to exited threads to list those that are in
1428 * the data file. Off-cpu events are synthesized after other events and
1429 * reference exited threads.
1430 */
1431 symbol_conf.keep_exited_threads = true;
1432
7f929aea 1433 annotation_options__init();
217b7d41 1434
ecc4c561
ACM
1435 ret = perf_config(report__config, &report);
1436 if (ret)
a37338aa 1437 goto exit;
00c7e1f1 1438
655000e7 1439 argc = parse_options(argc, argv, options, report_usage, 0);
b3f38fc2
NK
1440 if (argc) {
1441 /*
1442 * Special case: if there's an argument left then assume that
1443 * it's a symbol filter:
1444 */
1445 if (argc > 1)
1446 usage_with_options(report_usage, options);
1447
1448 report.symbol_filter_str = argv[0];
1449 }
655000e7 1450
56d9117c 1451 if (disassembler_style) {
14953f03
NK
1452 annotate_opts.disassembler_style = strdup(disassembler_style);
1453 if (!annotate_opts.disassembler_style)
56d9117c
IR
1454 return -ENOMEM;
1455 }
1456 if (objdump_path) {
14953f03
NK
1457 annotate_opts.objdump_path = strdup(objdump_path);
1458 if (!annotate_opts.objdump_path)
56d9117c
IR
1459 return -ENOMEM;
1460 }
57594454
IR
1461 if (addr2line_path) {
1462 symbol_conf.addr2line_path = strdup(addr2line_path);
1463 if (!symbol_conf.addr2line_path)
1464 return -ENOMEM;
1465 }
56d9117c 1466
7f929aea 1467 if (annotate_check_args() < 0) {
a37338aa
RM
1468 ret = -EINVAL;
1469 goto exit;
1470 }
3b0b16bf 1471
6439d7d1
ACM
1472 if (report.mmaps_mode)
1473 report.tasks_mode = true;
1474
2e989f82 1475 if (dump_trace && report.disable_order)
977f739b
JO
1476 report.tool.ordered_events = false;
1477
27fafab5
NK
1478 if (quiet)
1479 perf_quiet_option();
1480
a3df50ab
JC
1481 ret = symbol__validate_sym_arguments();
1482 if (ret)
a37338aa 1483 goto exit;
36c8bb56 1484
fa372aae 1485 if (report.inverted_callchain)
d797fdc5 1486 callchain_param.order = ORDER_CALLER;
792aeafa
NK
1487 if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
1488 callchain_param.order = ORDER_CALLER;
d797fdc5 1489
1c5c25b3 1490 if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
188bb5e2
AH
1491 (int)itrace_synth_opts.callchain_sz > report.max_stack)
1492 report.max_stack = itrace_synth_opts.callchain_sz;
1493
70cb4e96 1494 if (!input_name || !strlen(input_name)) {
efad1415 1495 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
70cb4e96 1496 input_name = "-";
efad1415 1497 else
70cb4e96 1498 input_name = "perf.data";
efad1415 1499 }
ad0de097 1500
2d4f2799
JO
1501 data.path = input_name;
1502 data.force = symbol_conf.force;
f5fc1412 1503
ad0de097 1504repeat:
2681bd85 1505 session = perf_session__new(&data, &report.tool);
a37338aa
RM
1506 if (IS_ERR(session)) {
1507 ret = PTR_ERR(session);
1508 goto exit;
1509 }
993ac88d 1510
ef4b1a53
ACM
1511 ret = evswitch__init(&report.evswitch, session->evlist, stderr);
1512 if (ret)
a37338aa 1513 goto exit;
ef4b1a53 1514
cb62c6f1
AB
1515 if (zstd_init(&(session->zstd_data), 0) < 0)
1516 pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
1517
94786b67
JO
1518 if (report.queue_size) {
1519 ordered_events__set_alloc_size(&session->ordered_events,
1520 report.queue_size);
1521 }
1522
520a2ebc
AH
1523 session->itrace_synth_opts = &itrace_synth_opts;
1524
993ac88d
SE
1525 report.session = session;
1526
1527 has_br_stack = perf_header__has_feat(&session->header,
1528 HEADER_BRANCH_STACK);
b3c2cc2b 1529 if (evlist__combined_sample_type(session->evlist) & PERF_SAMPLE_STACK_USER)
10ccbc1c 1530 has_br_stack = false;
efad1415 1531
57b5de46 1532 setup_forced_leader(&report, session->evlist);
ad52b8cb 1533
9d2dc632 1534 if (symbol_conf.group_sort_idx && evlist__nr_groups(session->evlist) == 0) {
429a5f9d
JY
1535 parse_options_usage(NULL, options, "group-sort-idx", 0);
1536 ret = -EINVAL;
1537 goto error;
1538 }
1539
ec90e42c 1540 if (itrace_synth_opts.last_branch || itrace_synth_opts.add_last_branch)
fb9fab66
AH
1541 has_br_stack = true;
1542
f9a7be7c
JY
1543 if (has_br_stack && branch_call_mode)
1544 symbol_conf.show_branchflag_count = true;
1545
2d78b189
JY
1546 memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat));
1547
fa94c36c
AK
1548 /*
1549 * Branch mode is a tristate:
1550 * -1 means default, so decide based on the file having branch data.
1551 * 0/1 means the user chose a mode.
1552 */
1553 if (((branch_mode == -1 && has_br_stack) || branch_mode == 1) &&
fefd2d96 1554 !branch_call_mode) {
55369fc1 1555 sort__mode = SORT_MODE__BRANCH;
793aaaab
NK
1556 symbol_conf.cumulate_callchain = false;
1557 }
fa94c36c 1558 if (branch_call_mode) {
09a6a1b0 1559 callchain_param.key = CCKEY_ADDRESS;
6fa9c3e7 1560 callchain_param.branch_callstack = true;
fa94c36c
AK
1561 symbol_conf.use_callchain = true;
1562 callchain_register_param(&callchain_param);
1563 if (sort_order == NULL)
1564 sort_order = "srcline,symbol,dso";
1565 }
993ac88d 1566
f4f7e28d 1567 if (report.mem_mode) {
55369fc1 1568 if (sort__mode == SORT_MODE__BRANCH) {
a4210141 1569 pr_err("branch and mem mode incompatible\n");
f4f7e28d
SE
1570 goto error;
1571 }
afab87b9 1572 sort__mode = SORT_MODE__MEMORY;
793aaaab 1573 symbol_conf.cumulate_callchain = false;
f4f7e28d 1574 }
a68c2c58 1575
4251446d
NK
1576 if (symbol_conf.report_hierarchy) {
1577 /* disable incompatible options */
4251446d
NK
1578 symbol_conf.cumulate_callchain = false;
1579
1580 if (field_order) {
1581 pr_err("Error: --hierarchy and --fields options cannot be used together\n");
1582 parse_options_usage(report_usage, options, "F", 1);
1583 parse_options_usage(NULL, options, "hierarchy", 0);
1584 goto error;
1585 }
1586
52225036 1587 perf_hpp_list.need_collapse = true;
4251446d
NK
1588 }
1589
712d36db
SS
1590 if (report.use_stdio)
1591 use_browser = 0;
3402ae0a 1592#ifdef HAVE_SLANG_SUPPORT
712d36db
SS
1593 else if (report.use_tui)
1594 use_browser = 1;
3402ae0a 1595#endif
557cc18e 1596#ifdef HAVE_GTK2_SUPPORT
712d36db
SS
1597 else if (report.use_gtk)
1598 use_browser = 2;
557cc18e 1599#endif
712d36db 1600
b138f42e
NK
1601 /* Force tty output for header output and per-thread stat. */
1602 if (report.header || report.header_only || report.show_threads)
5cfe2c82 1603 use_browser = 0;
114f709e
DCC
1604 if (report.header || report.header_only)
1605 report.tool.show_feat_hdr = SHOW_FEAT_HEADER;
1606 if (report.show_full_info)
1607 report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
930f8b34 1608 if (report.stats_mode || report.tasks_mode)
a4a4d0a7 1609 use_browser = 0;
930f8b34 1610 if (report.stats_mode && report.tasks_mode) {
6439d7d1 1611 pr_err("Error: --tasks and --mmaps can't be used together with --stats\n");
930f8b34
JO
1612 goto error;
1613 }
5cfe2c82 1614
6f7164fa
JY
1615 if (report.total_cycles_mode) {
1616 if (sort__mode != SORT_MODE__BRANCH)
1617 report.total_cycles_mode = false;
7fa46cbf 1618 else
848a5e50 1619 sort_order = NULL;
6f7164fa
JY
1620 }
1621
4bceffbc
NK
1622 if (strcmp(input_name, "-") != 0)
1623 setup_browser(true);
22af969e 1624 else
4bceffbc 1625 use_browser = 0;
4bceffbc 1626
ec6ae74f
JY
1627 if (sort_order && strstr(sort_order, "ipc")) {
1628 parse_options_usage(report_usage, options, "s", 1);
1629 goto error;
1630 }
1631
1632 if (sort_order && strstr(sort_order, "symbol")) {
1633 if (sort__mode == SORT_MODE__BRANCH) {
1634 snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1635 sort_order, "ipc_lbr");
1636 report.symbol_ipc = true;
1637 } else {
1638 snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1639 sort_order, "ipc_null");
1640 }
1641
1642 sort_order = sort_tmp;
1643 }
1644
5e3b810a 1645 if ((last_key != K_SWITCH_INPUT_DATA && last_key != K_RELOAD) &&
0feba17b 1646 (setup_sorting(session->evlist) < 0)) {
9887804d
JO
1647 if (sort_order)
1648 parse_options_usage(report_usage, options, "s", 1);
1649 if (field_order)
1650 parse_options_usage(sort_order ? NULL : report_usage,
1651 options, "F", 1);
1652 goto error;
1653 }
1654
27fafab5 1655 if ((report.header || report.header_only) && !quiet) {
5cfe2c82
JO
1656 perf_session__fprintf_info(session, stdout,
1657 report.show_full_info);
07a716ff 1658 if (report.header_only) {
03de8656
NK
1659 if (data.is_pipe) {
1660 /*
1661 * we need to process first few records
1662 * which contains PERF_RECORD_HEADER_FEATURE.
1663 */
1664 perf_session__process_events(session);
1665 }
07a716ff
TS
1666 ret = 0;
1667 goto error;
1668 }
930f8b34
JO
1669 } else if (use_browser == 0 && !quiet &&
1670 !report.stats_mode && !report.tasks_mode) {
5cfe2c82
JO
1671 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
1672 stdout);
1673 }
1674
ef7b93a1 1675 /*
6692c262 1676 * Only in the TUI browser we are doing integrated annotation,
ef7b93a1
ACM
1677 * so don't allocate extra space that won't be used in the stdio
1678 * implementation.
1679 */
6f7164fa
JY
1680 if (ui__has_annotation() || report.symbol_ipc ||
1681 report.total_cycles_mode) {
b01141f4
ACM
1682 ret = symbol__annotation_init();
1683 if (ret < 0)
1684 goto error;
80d50cae
ACM
1685 /*
1686 * For searching by name on the "Browse map details".
1687 * providing it only in verbose mode not to bloat too
1688 * much struct symbol.
1689 */
bb963e16 1690 if (verbose > 0) {
80d50cae
ACM
1691 /*
1692 * XXX: Need to provide a less kludgy way to ask for
1693 * more space per symbol, the u32 is for the index on
1694 * the ui browser.
1695 * See symbol__browser_index.
1696 */
1697 symbol_conf.priv_size += sizeof(u32);
80d50cae 1698 }
7f929aea 1699 annotation_config__init();
80d50cae 1700 }
655000e7 1701
0a7e6d1b 1702 if (symbol__init(&session->header.env) < 0)
993ac88d 1703 goto error;
53cb8bc2 1704
284c4e18
JY
1705 if (report.time_str) {
1706 ret = perf_time__parse_for_ranges(report.time_str, session,
1707 &report.ptime_range,
1708 &report.range_size,
1709 &report.range_num);
1710 if (ret < 0)
0a3cc3ae 1711 goto error;
4885c90c
AH
1712
1713 itrace_synth_opts__set_time_range(&itrace_synth_opts,
1714 report.ptime_range,
1715 report.range_num);
46690a80
DA
1716 }
1717
378ef0f5 1718#ifdef HAVE_LIBTRACEEVENT
ea85ab24 1719 if (session->tevent.pevent &&
ece2a4f4
TSV
1720 tep_set_function_resolver(session->tevent.pevent,
1721 machine__resolve_kernel_addr,
1722 &session->machines.host) < 0) {
ea85ab24
WY
1723 pr_err("%s: failed to set libtraceevent function resolver\n",
1724 __func__);
1725 return -1;
1726 }
378ef0f5 1727#endif
08e71542 1728 sort__setup_elide(stdout);
25903407 1729
993ac88d 1730 ret = __cmd_report(&report);
5e3b810a 1731 if (ret == K_SWITCH_INPUT_DATA || ret == K_RELOAD) {
ad0de097 1732 perf_session__delete(session);
0feba17b 1733 last_key = K_SWITCH_INPUT_DATA;
ad0de097
FT
1734 goto repeat;
1735 } else
1736 ret = 0;
1737
993ac88d 1738error:
4885c90c
AH
1739 if (report.ptime_range) {
1740 itrace_synth_opts__clear_time_range(&itrace_synth_opts);
284c4e18 1741 zfree(&report.ptime_range);
4885c90c 1742 }
6f7164fa 1743
cca0cc76
JY
1744 if (report.block_reports) {
1745 block_info__free_report(report.block_reports,
1746 report.nr_block_reports);
1747 report.block_reports = NULL;
1748 }
6f7164fa 1749
cb62c6f1 1750 zstd_fini(&(session->zstd_data));
993ac88d 1751 perf_session__delete(session);
a37338aa 1752exit:
7f929aea 1753 annotation_options__exit();
a37338aa
RM
1754 free(sort_order_help);
1755 free(field_order_help);
993ac88d 1756 return ret;
53cb8bc2 1757}