Linux Perf
builtin-annotate.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-annotate.c
4  *
5  * Builtin annotate 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  */
9 #include "builtin.h"
10 
11 #include "util/util.h"
12 #include "util/color.h"
13 #include <linux/list.h>
14 #include "util/cache.h"
15 #include <linux/rbtree.h>
16 #include "util/symbol.h"
17 
18 #include "perf.h"
19 #include "util/debug.h"
20 
21 #include "util/evlist.h"
22 #include "util/evsel.h"
23 #include "util/annotate.h"
24 #include "util/event.h"
25 #include <subcmd/parse-options.h>
26 #include "util/parse-events.h"
27 #include "util/thread.h"
28 #include "util/sort.h"
29 #include "util/hist.h"
30 #include "util/session.h"
31 #include "util/tool.h"
32 #include "util/data.h"
33 #include "arch/common.h"
34 #include "util/block-range.h"
35 
36 #include <dlfcn.h>
37 #include <errno.h>
38 #include <linux/bitmap.h>
39 
40 struct perf_annotate {
41  struct perf_tool tool;
47  bool group_set;
48  const char *sym_hist_filter;
49  const char *cpu_list;
50  DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
51 };
52 
53 /*
54  * Given one basic block:
55  *
56  * from to branch_i
57  * * ----> *
58  * |
59  * | block
60  * v
61  * * ----> *
62  * from to branch_i+1
63  *
64  * where the horizontal are the branches and the vertical is the executed
65  * block of instructions.
66  *
67  * We count, for each 'instruction', the number of blocks that covered it as
68  * well as count the ratio each branch is taken.
69  *
70  * We can do this without knowing the actual instruction stream by keeping
71  * track of the address ranges. We break down ranges such that there is no
72  * overlap and iterate from the start until the end.
73  *
74  * @acme: once we parse the objdump output _before_ processing the samples,
75  * we can easily fold the branch.cycles IPC bits in.
76  */
78  struct addr_map_symbol *end,
79  struct branch_flags *flags)
80 {
81  struct symbol *sym = start->sym;
82  struct annotation *notes = sym ? symbol__annotation(sym) : NULL;
83  struct block_range_iter iter;
84  struct block_range *entry;
85 
86  /*
87  * Sanity; NULL isn't executable and the CPU cannot execute backwards
88  */
89  if (!start->addr || start->addr > end->addr)
90  return;
91 
92  iter = block_range__create(start->addr, end->addr);
93  if (!block_range_iter__valid(&iter))
94  return;
95 
96  /*
97  * First block in range is a branch target.
98  */
99  entry = block_range_iter(&iter);
100  assert(entry->is_target);
101  entry->entry++;
102 
103  do {
104  entry = block_range_iter(&iter);
105 
106  entry->coverage++;
107  entry->sym = sym;
108 
109  if (notes)
110  notes->max_coverage = max(notes->max_coverage, entry->coverage);
111 
112  } while (block_range_iter__next(&iter));
113 
114  /*
115  * Last block in rage is a branch.
116  */
117  entry = block_range_iter(&iter);
118  assert(entry->is_branch);
119  entry->taken++;
120  if (flags->predicted)
121  entry->pred++;
122 }
123 
124 static void process_branch_stack(struct branch_stack *bs, struct addr_location *al,
125  struct perf_sample *sample)
126 {
127  struct addr_map_symbol *prev = NULL;
128  struct branch_info *bi;
129  int i;
130 
131  if (!bs || !bs->nr)
132  return;
133 
134  bi = sample__resolve_bstack(sample, al);
135  if (!bi)
136  return;
137 
138  for (i = bs->nr - 1; i >= 0; i--) {
139  /*
140  * XXX filter against symbol
141  */
142  if (prev)
143  process_basic_block(prev, &bi[i].from, &bi[i].flags);
144  prev = &bi[i].to;
145  }
146 
147  free(bi);
148 }
149 
151  struct addr_location *al __maybe_unused,
152  bool single __maybe_unused,
153  void *arg __maybe_unused)
154 {
155  struct hist_entry *he = iter->he;
156  struct branch_info *bi;
157  struct perf_sample *sample = iter->sample;
158  struct perf_evsel *evsel = iter->evsel;
159  int err;
160 
161  hist__account_cycles(sample->branch_stack, al, sample, false);
162 
163  bi = he->branch_info;
164  err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
165 
166  if (err)
167  goto out;
168 
169  err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
170 
171 out:
172  return err;
173 }
174 
175 static int process_branch_callback(struct perf_evsel *evsel,
176  struct perf_sample *sample,
177  struct addr_location *al __maybe_unused,
178  struct perf_annotate *ann,
179  struct machine *machine)
180 {
181  struct hist_entry_iter iter = {
182  .evsel = evsel,
183  .sample = sample,
184  .add_entry_cb = hist_iter__branch_callback,
185  .hide_unresolved = symbol_conf.hide_unresolved,
186  .ops = &hist_iter_branch,
187  };
188 
189  struct addr_location a;
190  int ret;
191 
192  if (machine__resolve(machine, &a, sample) < 0)
193  return -1;
194 
195  if (a.sym == NULL)
196  return 0;
197 
198  if (a.map != NULL)
199  a.map->dso->hit = 1;
200 
201  ret = hist_entry_iter__add(&iter, &a, PERF_MAX_STACK_DEPTH, ann);
202  return ret;
203 }
204 
205 static bool has_annotation(struct perf_annotate *ann)
206 {
207  return ui__has_annotation() || ann->use_stdio2;
208 }
209 
210 static int perf_evsel__add_sample(struct perf_evsel *evsel,
211  struct perf_sample *sample,
212  struct addr_location *al,
213  struct perf_annotate *ann,
214  struct machine *machine)
215 {
216  struct hists *hists = evsel__hists(evsel);
217  struct hist_entry *he;
218  int ret;
219 
220  if ((!ann->has_br_stack || !has_annotation(ann)) &&
221  ann->sym_hist_filter != NULL &&
222  (al->sym == NULL ||
223  strcmp(ann->sym_hist_filter, al->sym->name) != 0)) {
224  /* We're only interested in a symbol named sym_hist_filter */
225  /*
226  * FIXME: why isn't this done in the symbol_filter when loading
227  * the DSO?
228  */
229  if (al->sym != NULL) {
230  rb_erase(&al->sym->rb_node,
231  &al->map->dso->symbols);
232  symbol__delete(al->sym);
234  }
235  return 0;
236  }
237 
238  /*
239  * XXX filtered samples can still have branch entires pointing into our
240  * symbol and are missed.
241  */
242  process_branch_stack(sample->branch_stack, al, sample);
243 
244  if (ann->has_br_stack && has_annotation(ann))
245  return process_branch_callback(evsel, sample, al, ann, machine);
246 
247  he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
248  if (he == NULL)
249  return -ENOMEM;
250 
251  ret = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
252  hists__inc_nr_samples(hists, true);
253  return ret;
254 }
255 
257  union perf_event *event,
258  struct perf_sample *sample,
259  struct perf_evsel *evsel,
260  struct machine *machine)
261 {
262  struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool);
263  struct addr_location al;
264  int ret = 0;
265 
266  if (machine__resolve(machine, &al, sample) < 0) {
267  pr_warning("problem processing %d event, skipping it.\n",
268  event->header.type);
269  return -1;
270  }
271 
272  if (ann->cpu_list && !test_bit(sample->cpu, ann->cpu_bitmap))
273  goto out_put;
274 
275  if (!al.filtered &&
276  perf_evsel__add_sample(evsel, sample, &al, ann, machine)) {
277  pr_warning("problem incrementing symbol count, "
278  "skipping event\n");
279  ret = -1;
280  }
281 out_put:
282  addr_location__put(&al);
283  return ret;
284 }
285 
286 static int hist_entry__tty_annotate(struct hist_entry *he,
287  struct perf_evsel *evsel,
288  struct perf_annotate *ann)
289 {
290  if (!ann->use_stdio2)
291  return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel, &ann->opts);
292 
293  return symbol__tty_annotate2(he->ms.sym, he->ms.map, evsel, &ann->opts);
294 }
295 
296 static void hists__find_annotations(struct hists *hists,
297  struct perf_evsel *evsel,
298  struct perf_annotate *ann)
299 {
300  struct rb_node *nd = rb_first(&hists->entries), *next;
301  int key = K_RIGHT;
302 
303  while (nd) {
304  struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
305  struct annotation *notes;
306 
307  if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
308  goto find_next;
309 
310  if (ann->sym_hist_filter &&
311  (strcmp(he->ms.sym->name, ann->sym_hist_filter) != 0))
312  goto find_next;
313 
314  notes = symbol__annotation(he->ms.sym);
315  if (notes->src == NULL) {
316 find_next:
317  if (key == K_LEFT)
318  nd = rb_prev(nd);
319  else
320  nd = rb_next(nd);
321  continue;
322  }
323 
324  if (use_browser == 2) {
325  int ret;
326  int (*annotate)(struct hist_entry *he,
327  struct perf_evsel *evsel,
328  struct hist_browser_timer *hbt);
329 
330  annotate = dlsym(perf_gtk_handle,
331  "hist_entry__gtk_annotate");
332  if (annotate == NULL) {
333  ui__error("GTK browser not found!\n");
334  return;
335  }
336 
337  ret = annotate(he, evsel, NULL);
338  if (!ret || !ann->skip_missing)
339  return;
340 
341  /* skip missing symbols */
342  nd = rb_next(nd);
343  } else if (use_browser == 1) {
344  key = hist_entry__tui_annotate(he, evsel, NULL, &ann->opts);
345 
346  switch (key) {
347  case -1:
348  if (!ann->skip_missing)
349  return;
350  /* fall through */
351  case K_RIGHT:
352  next = rb_next(nd);
353  break;
354  case K_LEFT:
355  next = rb_prev(nd);
356  break;
357  default:
358  return;
359  }
360 
361  if (next != NULL)
362  nd = next;
363  } else {
364  hist_entry__tty_annotate(he, evsel, ann);
365  nd = rb_next(nd);
366  /*
367  * Since we have a hist_entry per IP for the same
368  * symbol, free he->ms.sym->src to signal we already
369  * processed this symbol.
370  */
371  zfree(&notes->src->cycles_hist);
372  zfree(&notes->src);
373  }
374  }
375 }
376 
377 static int __cmd_annotate(struct perf_annotate *ann)
378 {
379  int ret;
380  struct perf_session *session = ann->session;
381  struct perf_evsel *pos;
382  u64 total_nr_samples;
383 
384  if (ann->cpu_list) {
385  ret = perf_session__cpu_bitmap(session, ann->cpu_list,
386  ann->cpu_bitmap);
387  if (ret)
388  goto out;
389  }
390 
391  if (!ann->opts.objdump_path) {
392  ret = perf_env__lookup_objdump(&session->header.env,
393  &ann->opts.objdump_path);
394  if (ret)
395  goto out;
396  }
397 
398  ret = perf_session__process_events(session);
399  if (ret)
400  goto out;
401 
402  if (dump_trace) {
403  perf_session__fprintf_nr_events(session, stdout);
404  perf_evlist__fprintf_nr_events(session->evlist, stdout);
405  goto out;
406  }
407 
408  if (verbose > 3)
409  perf_session__fprintf(session, stdout);
410 
411  if (verbose > 2)
412  perf_session__fprintf_dsos(session, stdout);
413 
414  total_nr_samples = 0;
415  evlist__for_each_entry(session->evlist, pos) {
416  struct hists *hists = evsel__hists(pos);
417  u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
418 
419  if (nr_samples > 0) {
420  total_nr_samples += nr_samples;
421  hists__collapse_resort(hists, NULL);
422  /* Don't sort callchain */
423  perf_evsel__reset_sample_bit(pos, CALLCHAIN);
424  perf_evsel__output_resort(pos, NULL);
425 
426  if (symbol_conf.event_group &&
428  continue;
429 
430  hists__find_annotations(hists, pos, ann);
431  }
432  }
433 
434  if (total_nr_samples == 0) {
435  ui__error("The %s file has no samples!\n", session->data->file.path);
436  goto out;
437  }
438 
439  if (use_browser == 2) {
440  void (*show_annotations)(void);
441 
442  show_annotations = dlsym(perf_gtk_handle,
443  "perf_gtk__show_annotations");
444  if (show_annotations == NULL) {
445  ui__error("GTK browser not found!\n");
446  goto out;
447  }
448  show_annotations();
449  }
450 
451 out:
452  return ret;
453 }
454 
455 static const char * const annotate_usage[] = {
456  "perf annotate [<options>]",
457  NULL
458 };
459 
460 int cmd_annotate(int argc, const char **argv)
461 {
462  struct perf_annotate annotate = {
463  .tool = {
465  .mmap = perf_event__process_mmap,
466  .mmap2 = perf_event__process_mmap2,
467  .comm = perf_event__process_comm,
468  .exit = perf_event__process_exit,
469  .fork = perf_event__process_fork,
470  .namespaces = perf_event__process_namespaces,
471  .attr = perf_event__process_attr,
472  .build_id = perf_event__process_build_id,
473  .tracing_data = perf_event__process_tracing_data,
474  .feature = perf_event__process_feature,
475  .ordered_events = true,
476  .ordering_requires_timestamps = true,
477  },
479  };
480  struct perf_data data = {
482  };
483  struct option options[] = {
484  OPT_STRING('i', "input", &input_name, "file",
485  "input file name"),
486  OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
487  "only consider symbols in these dsos"),
488  OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol",
489  "symbol to annotate"),
490  OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"),
491  OPT_INCR('v', "verbose", &verbose,
492  "be more verbose (show symbol address, etc)"),
493  OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"),
494  OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
495  "dump raw trace in ASCII"),
496  OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
497  OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
498  OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
499  OPT_BOOLEAN(0, "stdio2", &annotate.use_stdio2, "Use the stdio interface"),
500  OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
501  "don't load vmlinux even if found"),
502  OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
503  "file", "vmlinux pathname"),
504  OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
505  "load module symbols - WARNING: use only with -k and LIVE kernel"),
506  OPT_BOOLEAN('l', "print-line", &annotate.opts.print_lines,
507  "print matching source lines (may be slow)"),
508  OPT_BOOLEAN('P', "full-paths", &annotate.opts.full_path,
509  "Don't shorten the displayed pathnames"),
510  OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing,
511  "Skip symbols that cannot be annotated"),
512  OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group,
513  &annotate.group_set,
514  "Show event group information together"),
515  OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
516  OPT_CALLBACK(0, "symfs", NULL, "directory",
517  "Look for files with symbols relative to this directory",
519  OPT_BOOLEAN(0, "source", &annotate.opts.annotate_src,
520  "Interleave source code with assembly code (default)"),
521  OPT_BOOLEAN(0, "asm-raw", &annotate.opts.show_asm_raw,
522  "Display raw encoding of assembly instructions (default)"),
523  OPT_STRING('M', "disassembler-style", &annotate.opts.disassembler_style, "disassembler style",
524  "Specify disassembler style (e.g. -M intel for intel syntax)"),
525  OPT_STRING(0, "objdump", &annotate.opts.objdump_path, "path",
526  "objdump binary to use for disassembly and annotations"),
527  OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
528  "Show event group information together"),
529  OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
530  "Show a column with the sum of periods"),
531  OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
532  "Show a column with the number of samples"),
533  OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
534  "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
535  stdio__config_color, "always"),
536  OPT_END()
537  };
538  int ret;
539 
540  set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE);
541  set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE);
542 
543 
544  ret = hists__init();
545  if (ret < 0)
546  return ret;
547 
548  argc = parse_options(argc, argv, options, annotate_usage, 0);
549  if (argc) {
550  /*
551  * Special case: if there's an argument left then assume that
552  * it's a symbol filter:
553  */
554  if (argc > 1)
555  usage_with_options(annotate_usage, options);
556 
557  annotate.sym_hist_filter = argv[0];
558  }
559 
560  if (symbol_conf.show_nr_samples && annotate.use_gtk) {
561  pr_err("--show-nr-samples is not available in --gtk mode at this time\n");
562  return ret;
563  }
564 
565  if (quiet)
567 
568  data.file.path = input_name;
569 
570  annotate.session = perf_session__new(&data, false, &annotate.tool);
571  if (annotate.session == NULL)
572  return -1;
573 
574  annotate.has_br_stack = perf_header__has_feat(&annotate.session->header,
576 
577  if (annotate.group_set)
579 
580  ret = symbol__annotation_init();
581  if (ret < 0)
582  goto out_delete;
583 
585 
587 
588  ret = symbol__init(&annotate.session->header.env);
589  if (ret < 0)
590  goto out_delete;
591 
592  if (annotate.use_stdio || annotate.use_stdio2)
593  use_browser = 0;
594  else if (annotate.use_tui)
595  use_browser = 1;
596  else if (annotate.use_gtk)
597  use_browser = 2;
598 
599  setup_browser(true);
600 
601  if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) {
603  if (setup_sorting(annotate.session->evlist) < 0)
604  usage_with_options(annotate_usage, options);
605  } else {
606  if (setup_sorting(NULL) < 0)
607  usage_with_options(annotate_usage, options);
608  }
609 
610  ret = __cmd_annotate(&annotate);
611 
612 out_delete:
613  /*
614  * Speed up the exit process, for large files this can
615  * take quite a while.
616  *
617  * XXX Enable this when using valgrind or if we ever
618  * librarize this command.
619  *
620  * Also experiment with obstacks to see how much speed
621  * up we'll get here.
622  *
623  * perf_session__delete(session);
624  */
625  return ret;
626 }
static void setup_sorting(struct perf_sched *sched, const struct option *options, const char *const usage_msg[])
bool event_group
Definition: symbol.h:93
int perf_event__process_attr(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_evlist **pevlist)
Definition: header.c:3721
const char * cpu_list
struct perf_sample * sample
Definition: hist.h:113
struct rb_node rb_node
Definition: symbol.h:56
enum perf_data_mode mode
Definition: data.h:22
struct perf_evlist * evlist
Definition: session.h:25
struct perf_data * data
Definition: session.h:36
int stdio__config_color(const struct option *opt __maybe_unused, const char *mode, int unset __maybe_unused)
Definition: setup.c:69
int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample)
Definition: event.c:1601
size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
Definition: session.c:2016
int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *opts)
Definition: annotate.c:827
const char * vmlinux_name
Definition: symbol.h:123
static int __cmd_annotate(struct perf_annotate *ann)
enum sort_mode sort__mode
Definition: sort.c:31
int ui__error(const char *format,...)
Definition: util.c:32
struct perf_tool tool
struct map_symbol ms
Definition: sort.h:98
int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, struct perf_evsel *evsel, u64 ip)
Definition: annotate.c:1022
void * perf_gtk_handle
Definition: setup.c:11
struct cyc_hist * cycles_hist
Definition: annotate.h:232
struct symbol * sym
Definition: symbol.h:181
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1385
struct map * map
Definition: symbol.h:180
Definition: hist.h:106
static int hist_entry__tty_annotate(struct hist_entry *he, struct perf_evsel *evsel, struct perf_annotate *ann)
static const char *const annotate_usage[]
static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine)
struct hist_entry * hists__add_entry(struct hists *hists, struct addr_location *al, struct symbol *sym_parent, struct branch_info *bi, struct mem_info *mi, struct perf_sample *sample, bool sample_self)
Definition: hist.c:627
int int err
Definition: 5sec.c:44
int hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
Definition: hist.c:1464
int perf_event__process_feature(struct perf_tool *tool, union perf_event *event, struct perf_session *session __maybe_unused)
Definition: header.c:3446
u64 nr
Definition: event.h:157
bool try_vmlinux_path
Definition: symbol.h:93
struct symbol * sym
Definition: block-range.h:21
struct perf_data_file file
Definition: data.h:18
static struct block_range * block_range_iter(struct block_range_iter *iter)
Definition: block-range.h:47
struct perf_env env
Definition: header.h:82
size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
Definition: session.c:2005
size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
Definition: session.c:2030
int perf_event__process_comm(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1273
static bool block_range_iter__valid(struct block_range_iter *iter)
Definition: block-range.h:61
int perf_event__process_exit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1416
static struct hists * evsel__hists(struct perf_evsel *evsel)
Definition: hist.h:217
u64 max_coverage
Definition: annotate.h:238
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1408
u8 annotate_warned
Definition: dso.h:163
bool use_modules
Definition: symbol.h:93
u8 hit
Definition: dso.h:162
const char * sym_hist_filter
struct rb_node rb_node
Definition: sort.h:91
int perf_event__process_build_id(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3922
#define pr_err(fmt,...)
Definition: json.h:21
struct hist_entry * he
Definition: hist.h:114
static int perf_evsel__add_sample(struct perf_evsel *evsel, struct perf_sample *sample, struct addr_location *al, struct perf_annotate *ann, struct machine *machine)
int use_browser
Definition: setup.c:12
Definition: sort.h:89
int perf_quiet_option(void)
Definition: debug.c:225
bool show_nr_samples
Definition: symbol.h:93
const char * key
Definition: bpf-loader.c:196
struct annotation_options opts
void addr_location__put(struct addr_location *al)
Definition: event.c:1661
struct map * map
Definition: symbol.h:210
void setup_browser(bool fallback_to_pager)
Definition: setup.c:76
int symbol__config_symfs(const struct option *opt __maybe_unused, const char *dir, int unset __maybe_unused)
Definition: symbol.c:2205
const char * objdump_path
Definition: annotate.h:83
#define K_RIGHT
Definition: keysyms.h:16
Definition: tool.h:44
int perf_env__lookup_objdump(struct perf_env *env, const char **path)
Definition: common.c:192
#define evlist__for_each_entry(evlist, evsel)
Definition: evlist.h:247
static int entry(u64 ip, struct unwind_info *ui)
Definition: unwind-libdw.c:71
struct dso * dso
Definition: map.h:45
u64 predicted
Definition: event.h:142
char name[0]
Definition: symbol.h:66
int symbol__annotation_init(void)
Definition: symbol.c:2097
bool hide_unresolved
Definition: symbol.h:93
const char * input_name
Definition: perf.c:40
struct symbol * sym
Definition: symbol.h:211
int symbol__tty_annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *opts)
Definition: annotate.c:2386
static struct annotation * symbol__annotation(struct symbol *sym)
Definition: annotate.h:293
#define event
int symbol__tty_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *opts)
Definition: annotate.c:2413
struct branch_stack * branch_stack
Definition: event.h:212
u32 cpu
Definition: event.h:201
Definition: data.h:17
const char * disassembler_style
Definition: annotate.h:84
int hists__init(void)
Definition: hist.c:2629
int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3854
const char * dso_list_str
Definition: symbol.h:131
#define zfree(ptr)
Definition: util.h:25
static void process_branch_stack(struct branch_stack *bs, struct addr_location *al, struct perf_sample *sample)
bool ui__has_annotation(void)
Definition: annotate.c:2438
struct perf_event_header header
Definition: event.h:624
struct rb_root symbols
Definition: dso.h:143
struct branch_info * branch_info
Definition: sort.h:134
u64 start
Definition: hists_common.c:25
void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, struct perf_sample *sample, bool nonany_branch_mode)
Definition: hist.c:2406
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
Definition: session.c:116
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1393
void perf_evlist__force_leader(struct perf_evlist *evlist)
Definition: evlist.c:1804
void dso__reset_find_symbol_cache(struct dso *dso)
Definition: symbol.c:478
struct annotation_options annotation__default_options
Definition: annotate.c:47
bool perf_header__has_feat(const struct perf_header *header, int feat)
Definition: header.c:86
#define K_LEFT
Definition: keysyms.h:13
int perf_session__process_events(struct perf_session *session)
Definition: session.c:1945
static bool has_annotation(struct perf_annotate *ann)
struct annotated_source * src
Definition: annotate.h:256
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS)
static int hist_iter__branch_callback(struct hist_entry_iter *iter, struct addr_location *al __maybe_unused, bool single __maybe_unused, void *arg __maybe_unused)
static int sym(yyscan_t scanner, int type, int config)
struct block_range_iter block_range__create(u64 start, u64 end)
Definition: block-range.c:79
struct symbol * sym
Definition: symbol.h:186
u32 flags
struct perf_evsel * evsel
Definition: hist.h:112
bool ignore_vmlinux
Definition: symbol.h:93
struct perf_header header
Definition: session.h:23
size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
Definition: hist.c:2440
bool dump_trace
Definition: debug.c:27
int symbol__init(struct perf_env *env)
Definition: symbol.c:2112
void free(void *)
struct addr_map_symbol to
Definition: symbol.h:194
struct addr_map_symbol from
Definition: symbol.h:193
struct events_stats stats
Definition: hist.h:85
const struct hist_iter_ops hist_iter_branch
Definition: hist.c:1012
u32 nr_events[PERF_RECORD_HEADER_MAX]
Definition: event.h:407
void symbol__delete(struct symbol *sym)
Definition: symbol.c:280
static bool perf_evsel__is_group_leader(const struct perf_evsel *evsel)
Definition: evsel.h:380
static bool block_range_iter__next(struct block_range_iter *iter)
Definition: block-range.h:52
#define MAX_NR_CPUS
Definition: perf.h:27
struct rb_root entries
Definition: hist.h:74
static int process_branch_callback(struct perf_evsel *evsel, struct perf_sample *sample, struct addr_location *al __maybe_unused, struct perf_annotate *ann, struct machine *machine)
#define perf_evsel__reset_sample_bit(evsel, bit)
Definition: evsel.h:263
void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog)
Definition: hist.c:1756
int verbose
Definition: jevents.c:53
struct branch_info * sample__resolve_bstack(struct perf_sample *sample, struct addr_location *al)
Definition: machine.c:1928
void annotation_config__init(void)
Definition: annotate.c:2788
Definition: symbol.h:55
#define pr_warning(fmt,...)
Definition: debug.h:25
int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap)
Definition: session.c:2051
Definition: hist.h:71
bool force
Definition: data.h:20
static void hists__find_annotations(struct hists *hists, struct perf_evsel *evsel, struct perf_annotate *ann)
int cmd_annotate(int argc, const char **argv)
int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1281
int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, struct perf_evsel *evsel)
Definition: annotate.c:1016
void hists__inc_nr_samples(struct hists *hists, bool filtered)
Definition: hist.c:2129
struct perf_session * session
bool show_total_period
Definition: symbol.h:93
static void process_basic_block(struct addr_map_symbol *start, struct addr_map_symbol *end, struct branch_flags *flags)
const char * path
Definition: data.h:13
int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, int max_stack_depth, void *arg)
Definition: hist.c:1036
event_sample sample
Definition: tool.h:45
bool quiet
Definition: builtin-probe.c:54