Blame view
tools/perf/builtin-annotate.c
13.5 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
8035e4288 perf_counter tool... |
2 3 4 5 6 7 8 9 10 11 |
/* * builtin-annotate.c * * Builtin annotate command: Analyze the perf.data input file, * look up and read DSOs and symbol information and display * a histogram of results, along various sorting keys. */ #include "builtin.h" #include "util/util.h" |
8035e4288 perf_counter tool... |
12 |
#include "util/color.h" |
5da502585 perf_counter tool... |
13 |
#include <linux/list.h> |
8035e4288 perf_counter tool... |
14 |
#include "util/cache.h" |
43cbcd8ac perf_counter tool... |
15 |
#include <linux/rbtree.h> |
8035e4288 perf_counter tool... |
16 |
#include "util/symbol.h" |
8035e4288 perf_counter tool... |
17 18 |
#include "perf.h" |
8f28827a1 perf tools: Libra... |
19 |
#include "util/debug.h" |
8035e4288 perf_counter tool... |
20 |
|
e248de331 perf tools: Impro... |
21 22 |
#include "util/evlist.h" #include "util/evsel.h" |
78f7defed perf annotate: Mo... |
23 |
#include "util/annotate.h" |
62daacb51 perf tools: Reorg... |
24 |
#include "util/event.h" |
4b6ab94ea perf subcmd: Crea... |
25 |
#include <subcmd/parse-options.h> |
8035e4288 perf_counter tool... |
26 |
#include "util/parse-events.h" |
6baa0a5ae perf tools: Facto... |
27 |
#include "util/thread.h" |
dd68ada2d perf tools: Creat... |
28 |
#include "util/sort.h" |
3d1d07ecd perf tools: Put c... |
29 |
#include "util/hist.h" |
94c744b6c perf tools: Intro... |
30 |
#include "util/session.h" |
45694aa77 perf tools: Renam... |
31 |
#include "util/tool.h" |
f5fc14124 perf tools: Add d... |
32 |
#include "util/data.h" |
68e94f4eb perf tools: Try t... |
33 |
#include "arch/common.h" |
70fbe0574 perf annotate: Ad... |
34 |
#include "util/block-range.h" |
8035e4288 perf_counter tool... |
35 |
|
fc67297b1 perf tools: Separ... |
36 |
#include <dlfcn.h> |
a43783aee perf tools: Inclu... |
37 |
#include <errno.h> |
5d67be97f perf report/annot... |
38 |
#include <linux/bitmap.h> |
d20deb64e perf tools: Pass ... |
39 |
struct perf_annotate { |
45694aa77 perf tools: Renam... |
40 |
struct perf_tool tool; |
fa10f316d perf annotate: Mo... |
41 42 |
struct perf_session *session; bool use_tui, use_stdio, use_gtk; |
7009cc34b perf annotate: Gr... |
43 44 |
bool full_paths; bool print_line; |
18c9e5c56 perf annotate: Ma... |
45 |
bool skip_missing; |
7009cc34b perf annotate: Gr... |
46 47 48 |
const char *sym_hist_filter; const char *cpu_list; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
d20deb64e perf tools: Pass ... |
49 |
}; |
5d67be97f perf report/annot... |
50 |
|
70fbe0574 perf annotate: Ad... |
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
/* * Given one basic block: * * from to branch_i * * ----> * * | * | block * v * * ----> * * from to branch_i+1 * * where the horizontal are the branches and the vertical is the executed * block of instructions. * * We count, for each 'instruction', the number of blocks that covered it as * well as count the ratio each branch is taken. * * We can do this without knowing the actual instruction stream by keeping * track of the address ranges. We break down ranges such that there is no * overlap and iterate from the start until the end. * * @acme: once we parse the objdump output _before_ processing the samples, * we can easily fold the branch.cycles IPC bits in. */ static void process_basic_block(struct addr_map_symbol *start, struct addr_map_symbol *end, struct branch_flags *flags) { struct symbol *sym = start->sym; struct annotation *notes = sym ? symbol__annotation(sym) : NULL; struct block_range_iter iter; struct block_range *entry; /* * Sanity; NULL isn't executable and the CPU cannot execute backwards */ if (!start->addr || start->addr > end->addr) return; iter = block_range__create(start->addr, end->addr); if (!block_range_iter__valid(&iter)) return; /* * First block in range is a branch target. */ entry = block_range_iter(&iter); assert(entry->is_target); entry->entry++; do { entry = block_range_iter(&iter); entry->coverage++; entry->sym = sym; if (notes) notes->max_coverage = max(notes->max_coverage, entry->coverage); } while (block_range_iter__next(&iter)); /* * Last block in rage is a branch. */ entry = block_range_iter(&iter); assert(entry->is_branch); entry->taken++; if (flags->predicted) entry->pred++; } static void process_branch_stack(struct branch_stack *bs, struct addr_location *al, struct perf_sample *sample) { struct addr_map_symbol *prev = NULL; struct branch_info *bi; int i; if (!bs || !bs->nr) return; bi = sample__resolve_bstack(sample, al); if (!bi) return; for (i = bs->nr - 1; i >= 0; i--) { /* * XXX filter against symbol */ if (prev) process_basic_block(prev, &bi[i].from, &bi[i].flags); prev = &bi[i].to; } free(bi); } |
d04b35f80 perf symbols: Add... |
147 |
static int perf_evsel__add_sample(struct perf_evsel *evsel, |
fd36f3dd7 perf hist: Pass s... |
148 |
struct perf_sample *sample, |
d20deb64e perf tools: Pass ... |
149 150 |
struct addr_location *al, struct perf_annotate *ann) |
8035e4288 perf_counter tool... |
151 |
{ |
4ea062ed4 perf evsel: Add h... |
152 |
struct hists *hists = evsel__hists(evsel); |
628ada0cb perf annotate: De... |
153 |
struct hist_entry *he; |
e248de331 perf tools: Impro... |
154 |
int ret; |
628ada0cb perf annotate: De... |
155 |
|
7009cc34b perf annotate: Gr... |
156 157 158 |
if (ann->sym_hist_filter != NULL && (al->sym == NULL || strcmp(ann->sym_hist_filter, al->sym->name) != 0)) { |
628ada0cb perf annotate: De... |
159 |
/* We're only interested in a symbol named sym_hist_filter */ |
facf3f062 perf tools: Check... |
160 161 162 163 |
/* * FIXME: why isn't this done in the symbol_filter when loading * the DSO? */ |
628ada0cb perf annotate: De... |
164 165 166 167 |
if (al->sym != NULL) { rb_erase(&al->sym->rb_node, &al->map->dso->symbols[al->map->type]); symbol__delete(al->sym); |
c0b4dffbc perf annotate: Re... |
168 |
dso__reset_find_symbol_cache(al->map->dso); |
628ada0cb perf annotate: De... |
169 170 171 |
} return 0; } |
70fbe0574 perf annotate: Ad... |
172 173 174 175 176 |
/* * XXX filtered samples can still have branch entires pointing into our * symbol and are missed. */ process_branch_stack(sample->branch_stack, al, sample); |
0102ef3ec perf hists: Renam... |
177 |
he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); |
9735abf11 perf tools: Move ... |
178 |
if (he == NULL) |
8035e4288 perf_counter tool... |
179 |
return -ENOMEM; |
628ada0cb perf annotate: De... |
180 |
|
bab89f6ae perf hists: Pass ... |
181 |
ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); |
4ea062ed4 perf evsel: Add h... |
182 |
hists__inc_nr_samples(hists, true); |
e248de331 perf tools: Impro... |
183 |
return ret; |
8035e4288 perf_counter tool... |
184 |
} |
45694aa77 perf tools: Renam... |
185 |
static int process_sample_event(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
186 |
union perf_event *event, |
8115d60c3 perf tools: Kill ... |
187 |
struct perf_sample *sample, |
9e69c2108 perf session: Pas... |
188 |
struct perf_evsel *evsel, |
743eb8686 perf tools: Resol... |
189 |
struct machine *machine) |
8035e4288 perf_counter tool... |
190 |
{ |
45694aa77 perf tools: Renam... |
191 |
struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool); |
1ed091c45 perf tools: Conso... |
192 |
struct addr_location al; |
b91fc39f4 perf machine: Pro... |
193 |
int ret = 0; |
6baa0a5ae perf tools: Facto... |
194 |
|
bb3eb5662 perf machine: Ren... |
195 |
if (machine__resolve(machine, &al, sample) < 0) { |
29a9f66d7 perf tools: Adjus... |
196 197 198 |
pr_warning("problem processing %d event, skipping it. ", event->header.type); |
8035e4288 perf_counter tool... |
199 200 |
return -1; } |
7009cc34b perf annotate: Gr... |
201 |
if (ann->cpu_list && !test_bit(sample->cpu, ann->cpu_bitmap)) |
b91fc39f4 perf machine: Pro... |
202 |
goto out_put; |
5d67be97f perf report/annot... |
203 |
|
d20deb64e perf tools: Pass ... |
204 |
if (!al.filtered && perf_evsel__add_sample(evsel, sample, &al, ann)) { |
29a9f66d7 perf tools: Adjus... |
205 206 207 |
pr_warning("problem incrementing symbol count, " "skipping event "); |
b91fc39f4 perf machine: Pro... |
208 |
ret = -1; |
8035e4288 perf_counter tool... |
209 |
} |
b91fc39f4 perf machine: Pro... |
210 211 212 |
out_put: addr_location__put(&al); return ret; |
8035e4288 perf_counter tool... |
213 |
} |
db8fd07a5 perf annotate: Pa... |
214 215 |
static int hist_entry__tty_annotate(struct hist_entry *he, struct perf_evsel *evsel, |
d20deb64e perf tools: Pass ... |
216 |
struct perf_annotate *ann) |
0b73da3f4 perf_counter tool... |
217 |
{ |
db8fd07a5 perf annotate: Pa... |
218 |
return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel, |
7009cc34b perf annotate: Gr... |
219 |
ann->print_line, ann->full_paths, 0, 0); |
0b73da3f4 perf_counter tool... |
220 |
} |
c824c4338 perf tools: Stop ... |
221 |
static void hists__find_annotations(struct hists *hists, |
db8fd07a5 perf annotate: Pa... |
222 |
struct perf_evsel *evsel, |
d20deb64e perf tools: Pass ... |
223 |
struct perf_annotate *ann) |
0b73da3f4 perf_counter tool... |
224 |
{ |
c824c4338 perf tools: Stop ... |
225 |
struct rb_node *nd = rb_first(&hists->entries), *next; |
cf9580036 perf ui browser: ... |
226 |
int key = K_RIGHT; |
0b73da3f4 perf_counter tool... |
227 |
|
46e3e055c perf annotate: Ad... |
228 |
while (nd) { |
ed52ce2e3 perf tools: Add -... |
229 |
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
78f7defed perf annotate: Mo... |
230 |
struct annotation *notes; |
0b73da3f4 perf_counter tool... |
231 |
|
46e3e055c perf annotate: Ad... |
232 233 |
if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) goto find_next; |
0b73da3f4 perf_counter tool... |
234 |
|
78f7defed perf annotate: Mo... |
235 |
notes = symbol__annotation(he->ms.sym); |
ce6f4fab4 perf annotate: Mo... |
236 |
if (notes->src == NULL) { |
46e3e055c perf annotate: Ad... |
237 |
find_next: |
cf9580036 perf ui browser: ... |
238 |
if (key == K_LEFT) |
46e3e055c perf annotate: Ad... |
239 240 241 |
nd = rb_prev(nd); else nd = rb_next(nd); |
e42049926 perf annotate: Us... |
242 |
continue; |
46e3e055c perf annotate: Ad... |
243 |
} |
e42049926 perf annotate: Us... |
244 |
|
2b676bf06 perf ui/gtk: Impl... |
245 |
if (use_browser == 2) { |
18c9e5c56 perf annotate: Ma... |
246 |
int ret; |
fc67297b1 perf tools: Separ... |
247 248 249 250 251 252 253 254 255 256 257 |
int (*annotate)(struct hist_entry *he, struct perf_evsel *evsel, struct hist_browser_timer *hbt); annotate = dlsym(perf_gtk_handle, "hist_entry__gtk_annotate"); if (annotate == NULL) { ui__error("GTK browser not found! "); return; } |
18c9e5c56 perf annotate: Ma... |
258 |
|
fc67297b1 perf tools: Separ... |
259 |
ret = annotate(he, evsel, NULL); |
18c9e5c56 perf annotate: Ma... |
260 261 262 263 264 |
if (!ret || !ann->skip_missing) return; /* skip missing symbols */ nd = rb_next(nd); |
2b676bf06 perf ui/gtk: Impl... |
265 |
} else if (use_browser == 1) { |
db8fd07a5 perf annotate: Pa... |
266 |
key = hist_entry__tui_annotate(he, evsel, NULL); |
46e3e055c perf annotate: Ad... |
267 |
switch (key) { |
18c9e5c56 perf annotate: Ma... |
268 269 270 271 |
case -1: if (!ann->skip_missing) return; /* fall through */ |
cf9580036 perf ui browser: ... |
272 |
case K_RIGHT: |
b50e003db perf ui browser: ... |
273 |
next = rb_next(nd); |
46e3e055c perf annotate: Ad... |
274 |
break; |
cf9580036 perf ui browser: ... |
275 |
case K_LEFT: |
b50e003db perf ui browser: ... |
276 |
next = rb_prev(nd); |
46e3e055c perf annotate: Ad... |
277 |
break; |
b50e003db perf ui browser: ... |
278 279 |
default: return; |
46e3e055c perf annotate: Ad... |
280 |
} |
b50e003db perf ui browser: ... |
281 282 283 |
if (next != NULL) nd = next; |
46e3e055c perf annotate: Ad... |
284 |
} else { |
db8fd07a5 perf annotate: Pa... |
285 |
hist_entry__tty_annotate(he, evsel, ann); |
46e3e055c perf annotate: Ad... |
286 287 288 |
nd = rb_next(nd); /* * Since we have a hist_entry per IP for the same |
ce6f4fab4 perf annotate: Mo... |
289 |
* symbol, free he->ms.sym->src to signal we already |
46e3e055c perf annotate: Ad... |
290 291 |
* processed this symbol. */ |
d4957633b perf report: Add ... |
292 |
zfree(¬es->src->cycles_hist); |
046625231 perf tools: Intro... |
293 |
zfree(¬es->src); |
46e3e055c perf annotate: Ad... |
294 |
} |
0b73da3f4 perf_counter tool... |
295 |
} |
0b73da3f4 perf_counter tool... |
296 |
} |
d20deb64e perf tools: Pass ... |
297 |
static int __cmd_annotate(struct perf_annotate *ann) |
8035e4288 perf_counter tool... |
298 |
{ |
bab81b624 perf annotate: Fi... |
299 |
int ret; |
fa10f316d perf annotate: Mo... |
300 |
struct perf_session *session = ann->session; |
e248de331 perf tools: Impro... |
301 302 |
struct perf_evsel *pos; u64 total_nr_samples; |
94c744b6c perf tools: Intro... |
303 |
|
7009cc34b perf annotate: Gr... |
304 305 306 |
if (ann->cpu_list) { ret = perf_session__cpu_bitmap(session, ann->cpu_list, ann->cpu_bitmap); |
5d67be97f perf report/annot... |
307 |
if (ret) |
fa10f316d perf annotate: Mo... |
308 |
goto out; |
5d67be97f perf report/annot... |
309 |
} |
68e94f4eb perf tools: Try t... |
310 |
if (!objdump_path) { |
eebd0bfca perf env: Rename ... |
311 |
ret = perf_env__lookup_objdump(&session->header.env); |
68e94f4eb perf tools: Try t... |
312 |
if (ret) |
fa10f316d perf annotate: Mo... |
313 |
goto out; |
68e94f4eb perf tools: Try t... |
314 |
} |
b7b61cbeb perf ordered_even... |
315 |
ret = perf_session__process_events(session); |
bab81b624 perf annotate: Fi... |
316 |
if (ret) |
fa10f316d perf annotate: Mo... |
317 |
goto out; |
8035e4288 perf_counter tool... |
318 |
|
62daacb51 perf tools: Reorg... |
319 |
if (dump_trace) { |
c8446b9bd perf hist: Make e... |
320 |
perf_session__fprintf_nr_events(session, stdout); |
2a1731fb8 perf session: Rem... |
321 |
perf_evlist__fprintf_nr_events(session->evlist, stdout); |
fa10f316d perf annotate: Mo... |
322 |
goto out; |
62daacb51 perf tools: Reorg... |
323 |
} |
8035e4288 perf_counter tool... |
324 |
|
da21d1b54 perf tools: Up th... |
325 |
if (verbose > 3) |
b3165f414 perf session: Mov... |
326 |
perf_session__fprintf(session, stdout); |
8035e4288 perf_counter tool... |
327 |
|
da21d1b54 perf tools: Up th... |
328 |
if (verbose > 2) |
cbf696809 perf machines: Ma... |
329 |
perf_session__fprintf_dsos(session, stdout); |
8035e4288 perf_counter tool... |
330 |
|
e248de331 perf tools: Impro... |
331 |
total_nr_samples = 0; |
e5cadb93d perf evlist: Rena... |
332 |
evlist__for_each_entry(session->evlist, pos) { |
4ea062ed4 perf evsel: Add h... |
333 |
struct hists *hists = evsel__hists(pos); |
e248de331 perf tools: Impro... |
334 335 336 337 |
u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; if (nr_samples > 0) { total_nr_samples += nr_samples; |
c1fb5651b perf tools: Show ... |
338 |
hists__collapse_resort(hists, NULL); |
f9db0d0f1 perf callchain: A... |
339 340 |
/* Don't sort callchain */ perf_evsel__reset_sample_bit(pos, CALLCHAIN); |
452ce03b1 perf hists: Intro... |
341 |
perf_evsel__output_resort(pos, NULL); |
b1dd44329 perf annotate: Ad... |
342 343 344 345 |
if (symbol_conf.event_group && !perf_evsel__is_group_leader(pos)) continue; |
db8fd07a5 perf annotate: Pa... |
346 |
hists__find_annotations(hists, pos, ann); |
e248de331 perf tools: Impro... |
347 348 |
} } |
8035e4288 perf_counter tool... |
349 |
|
e248de331 perf tools: Impro... |
350 |
if (total_nr_samples == 0) { |
fa10f316d perf annotate: Mo... |
351 352 353 |
ui__error("The %s file has no samples! ", session->file->path); goto out; |
e248de331 perf tools: Impro... |
354 |
} |
7a60ba948 perf gtk/annotate... |
355 |
|
fc67297b1 perf tools: Separ... |
356 357 358 359 360 361 362 363 |
if (use_browser == 2) { void (*show_annotations)(void); show_annotations = dlsym(perf_gtk_handle, "perf_gtk__show_annotations"); if (show_annotations == NULL) { ui__error("GTK browser not found! "); |
fa10f316d perf annotate: Mo... |
364 |
goto out; |
fc67297b1 perf tools: Separ... |
365 366 367 |
} show_annotations(); } |
7a60ba948 perf gtk/annotate... |
368 |
|
fa10f316d perf annotate: Mo... |
369 |
out: |
bab81b624 perf annotate: Fi... |
370 |
return ret; |
8035e4288 perf_counter tool... |
371 372 373 |
} static const char * const annotate_usage[] = { |
993452541 perf annotate: Fi... |
374 |
"perf annotate [<options>]", |
8035e4288 perf_counter tool... |
375 376 |
NULL }; |
b0ad8ea66 perf tools: Remov... |
377 |
int cmd_annotate(int argc, const char **argv) |
d20deb64e perf tools: Pass ... |
378 379 |
{ struct perf_annotate annotate = { |
45694aa77 perf tools: Renam... |
380 |
.tool = { |
d20deb64e perf tools: Pass ... |
381 382 |
.sample = process_sample_event, .mmap = perf_event__process_mmap, |
5c5e854bc perf tools: Add a... |
383 |
.mmap2 = perf_event__process_mmap2, |
d20deb64e perf tools: Pass ... |
384 |
.comm = perf_event__process_comm, |
ec4622f5f perf annotate: Ha... |
385 |
.exit = perf_event__process_exit, |
f62d3f0f4 perf event: No ne... |
386 |
.fork = perf_event__process_fork, |
f3b3614a2 perf tools: Add P... |
387 |
.namespaces = perf_event__process_namespaces, |
6ab11f3a3 perf annotate: Pr... |
388 389 |
.attr = perf_event__process_attr, .build_id = perf_event__process_build_id, |
f48495990 perf annotate: Pr... |
390 |
.tracing_data = perf_event__process_tracing_data, |
e9def1b2e perf tools: Add f... |
391 |
.feature = perf_event__process_feature, |
0a8cb85c2 perf tools: Renam... |
392 |
.ordered_events = true, |
d20deb64e perf tools: Pass ... |
393 394 |
.ordering_requires_timestamps = true, }, |
d20deb64e perf tools: Pass ... |
395 |
}; |
fa10f316d perf annotate: Mo... |
396 |
struct perf_data_file file = { |
fa10f316d perf annotate: Mo... |
397 398 |
.mode = PERF_DATA_MODE_READ, }; |
1ac39372e perf annotate std... |
399 |
struct option options[] = { |
70cb4e963 perf tools: Add a... |
400 |
OPT_STRING('i', "input", &input_name, "file", |
8035e4288 perf_counter tool... |
401 |
"input file name"), |
ac73c5a9c perf annotate: Al... |
402 403 |
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", "only consider symbols in these dsos"), |
7009cc34b perf annotate: Gr... |
404 |
OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol", |
0b73da3f4 perf_counter tool... |
405 |
"symbol to annotate"), |
fa10f316d perf annotate: Mo... |
406 |
OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), |
c05556421 perf: Fix endiann... |
407 |
OPT_INCR('v', "verbose", &verbose, |
8035e4288 perf_counter tool... |
408 |
"be more verbose (show symbol address, etc)"), |
eddaef889 perf annotate: Ad... |
409 |
OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"), |
8035e4288 perf_counter tool... |
410 411 |
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), |
2b676bf06 perf ui/gtk: Impl... |
412 |
OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"), |
7009cc34b perf annotate: Gr... |
413 414 |
OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"), OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"), |
b32d133ae perf symbols: Sim... |
415 416 417 |
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, |
429764873 perf_counter tool... |
418 |
"load module symbols - WARNING: use only with -k and LIVE kernel"), |
7009cc34b perf annotate: Gr... |
419 |
OPT_BOOLEAN('l', "print-line", &annotate.print_line, |
301406b9c perf annotate: Pr... |
420 |
"print matching source lines (may be slow)"), |
7009cc34b perf annotate: Gr... |
421 |
OPT_BOOLEAN('P', "full-paths", &annotate.full_paths, |
429764873 perf_counter tool... |
422 |
"Don't shorten the displayed pathnames"), |
18c9e5c56 perf annotate: Ma... |
423 424 |
OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing, "Skip symbols that cannot be annotated"), |
c8e667203 perf tools: make ... |
425 |
OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"), |
a70667090 perf tools: Set b... |
426 427 428 |
OPT_CALLBACK(0, "symfs", NULL, "directory", "Look for files with symbols relative to this directory", symbol__config_symfs), |
64c6f0c7f perf tools: Make ... |
429 |
OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src, |
3e6a2a7f3 perf annotate: Ma... |
430 |
"Interleave source code with assembly code (default)"), |
64c6f0c7f perf tools: Make ... |
431 |
OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw, |
3e6a2a7f3 perf annotate: Ma... |
432 |
"Display raw encoding of assembly instructions (default)"), |
f69b64f73 perf: Support set... |
433 434 |
OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", "Specify disassembler style (e.g. -M intel for intel syntax)"), |
7a4ec9388 perf tools: Allow... |
435 436 |
OPT_STRING(0, "objdump", &objdump_path, "path", "objdump binary to use for disassembly and annotations"), |
b1dd44329 perf annotate: Ad... |
437 438 |
OPT_BOOLEAN(0, "group", &symbol_conf.event_group, "Show event group information together"), |
0c4a5bcea perf annotate: Di... |
439 440 |
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), |
1ac39372e perf annotate std... |
441 442 |
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, "Show a column with the number of samples"), |
53fe4ba1d perf annotate: In... |
443 444 445 |
OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode", "'always' (default), 'never' or 'auto' only applicable to --stdio mode", stdio__config_color, "always"), |
8035e4288 perf_counter tool... |
446 |
OPT_END() |
d20deb64e perf tools: Pass ... |
447 |
}; |
1ac39372e perf annotate std... |
448 449 450 451 |
int ret; set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE); set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE); |
a635fc511 perf tools: Remov... |
452 |
|
1ac39372e perf annotate std... |
453 |
ret = hists__init(); |
a635fc511 perf tools: Remov... |
454 455 |
if (ret < 0) return ret; |
8035e4288 perf_counter tool... |
456 |
|
655000e7c perf symbols: Ado... |
457 |
argc = parse_options(argc, argv, options, annotate_usage, 0); |
50e19ef97 perf annotate: Ch... |
458 459 460 461 462 463 464 465 466 467 |
if (argc) { /* * Special case: if there's an argument left then assume that * it's a symbol filter: */ if (argc > 1) usage_with_options(annotate_usage, options); annotate.sym_hist_filter = argv[0]; } |
655000e7c perf symbols: Ado... |
468 |
|
9cef4b0b5 perf annotate bro... |
469 470 471 |
if (symbol_conf.show_nr_samples && annotate.use_gtk) { pr_err("--show-nr-samples is not available in --gtk mode at this time "); |
1ac39372e perf annotate std... |
472 473 |
return ret; } |
eddaef889 perf annotate: Ad... |
474 475 |
if (quiet) perf_quiet_option(); |
44848cdbb perf annotate: Fi... |
476 |
file.path = input_name; |
fa10f316d perf annotate: Mo... |
477 478 |
annotate.session = perf_session__new(&file, false, &annotate.tool); if (annotate.session == NULL) |
52e028349 perf tools: Modif... |
479 |
return -1; |
fa10f316d perf annotate: Mo... |
480 |
|
b01141f4f perf annotate: In... |
481 482 483 |
ret = symbol__annotation_init(); if (ret < 0) goto out_delete; |
75be6cf48 perf symbols: Mak... |
484 |
symbol_conf.try_vmlinux_path = true; |
0a7e6d1b6 perf tools: Check... |
485 |
ret = symbol__init(&annotate.session->header.env); |
fa10f316d perf annotate: Mo... |
486 487 |
if (ret < 0) goto out_delete; |
8035e4288 perf_counter tool... |
488 |
|
40184c46a perf tools: Pass ... |
489 |
if (setup_sorting(NULL) < 0) |
553099857 perf sort: Make s... |
490 |
usage_with_options(annotate_usage, options); |
8035e4288 perf_counter tool... |
491 |
|
3df668e74 perf annotate: De... |
492 493 494 495 496 497 498 499 |
if (annotate.use_stdio) use_browser = 0; else if (annotate.use_tui) use_browser = 1; else if (annotate.use_gtk) use_browser = 2; setup_browser(true); |
fa10f316d perf annotate: Mo... |
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
ret = __cmd_annotate(&annotate); out_delete: /* * Speed up the exit process, for large files this can * take quite a while. * * XXX Enable this when using valgrind or if we ever * librarize this command. * * Also experiment with obstacks to see how much speed * up we'll get here. * * perf_session__delete(session); */ return ret; |
8035e4288 perf_counter tool... |
516 |
} |