diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r-- | tools/perf/builtin-annotate.c | 80 |
1 files changed, 14 insertions, 66 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6b13a1ecf1e7..18ac5eaefc36 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "util/thread.h" | 24 | #include "util/thread.h" |
25 | #include "util/sort.h" | 25 | #include "util/sort.h" |
26 | #include "util/hist.h" | 26 | #include "util/hist.h" |
27 | #include "util/process_events.h" | ||
27 | 28 | ||
28 | static char const *input_name = "perf.data"; | 29 | static char const *input_name = "perf.data"; |
29 | 30 | ||
@@ -33,11 +34,9 @@ static int input; | |||
33 | static int full_paths; | 34 | static int full_paths; |
34 | 35 | ||
35 | static int print_line; | 36 | static int print_line; |
36 | static bool use_modules; | ||
37 | 37 | ||
38 | static unsigned long page_size; | 38 | static unsigned long page_size; |
39 | static unsigned long mmap_window = 32; | 39 | static unsigned long mmap_window = 32; |
40 | const char *vmlinux_name; | ||
41 | 40 | ||
42 | struct sym_hist { | 41 | struct sym_hist { |
43 | u64 sum; | 42 | u64 sum; |
@@ -55,6 +54,11 @@ struct sym_priv { | |||
55 | struct sym_ext *ext; | 54 | struct sym_ext *ext; |
56 | }; | 55 | }; |
57 | 56 | ||
57 | static struct symbol_conf symbol_conf = { | ||
58 | .priv_size = sizeof(struct sym_priv), | ||
59 | .try_vmlinux_path = true, | ||
60 | }; | ||
61 | |||
58 | static const char *sym_hist_filter; | 62 | static const char *sym_hist_filter; |
59 | 63 | ||
60 | static int symbol_filter(struct map *map __used, struct symbol *sym) | 64 | static int symbol_filter(struct map *map __used, struct symbol *sym) |
@@ -158,7 +162,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
158 | 162 | ||
159 | if (event->header.misc & PERF_RECORD_MISC_KERNEL) { | 163 | if (event->header.misc & PERF_RECORD_MISC_KERNEL) { |
160 | level = 'k'; | 164 | level = 'k'; |
161 | sym = kernel_maps__find_symbol(ip, &map, symbol_filter); | 165 | sym = kernel_maps__find_function(ip, &map, symbol_filter); |
162 | dump_printf(" ...... dso: %s\n", | 166 | dump_printf(" ...... dso: %s\n", |
163 | map ? map->dso->long_name : "<not found>"); | 167 | map ? map->dso->long_name : "<not found>"); |
164 | } else if (event->header.misc & PERF_RECORD_MISC_USER) { | 168 | } else if (event->header.misc & PERF_RECORD_MISC_USER) { |
@@ -167,7 +171,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
167 | if (map != NULL) { | 171 | if (map != NULL) { |
168 | got_map: | 172 | got_map: |
169 | ip = map->map_ip(map, ip); | 173 | ip = map->map_ip(map, ip); |
170 | sym = map__find_symbol(map, ip, symbol_filter); | 174 | sym = map__find_function(map, ip, symbol_filter); |
171 | } else { | 175 | } else { |
172 | /* | 176 | /* |
173 | * If this is outside of all known maps, | 177 | * If this is outside of all known maps, |
@@ -202,32 +206,6 @@ got_map: | |||
202 | } | 206 | } |
203 | 207 | ||
204 | static int | 208 | static int |
205 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | ||
206 | { | ||
207 | struct map *map = map__new(&event->mmap, NULL, 0); | ||
208 | struct thread *thread = threads__findnew(event->mmap.pid); | ||
209 | |||
210 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n", | ||
211 | (void *)(offset + head), | ||
212 | (void *)(long)(event->header.size), | ||
213 | event->mmap.pid, | ||
214 | (void *)(long)event->mmap.start, | ||
215 | (void *)(long)event->mmap.len, | ||
216 | (void *)(long)event->mmap.pgoff, | ||
217 | event->mmap.filename); | ||
218 | |||
219 | if (thread == NULL || map == NULL) { | ||
220 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | thread__insert_map(thread, map); | ||
225 | total_mmap++; | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int | ||
231 | process_comm_event(event_t *event, unsigned long offset, unsigned long head) | 209 | process_comm_event(event_t *event, unsigned long offset, unsigned long head) |
232 | { | 210 | { |
233 | struct thread *thread = threads__findnew(event->comm.pid); | 211 | struct thread *thread = threads__findnew(event->comm.pid); |
@@ -248,33 +226,6 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head) | |||
248 | } | 226 | } |
249 | 227 | ||
250 | static int | 228 | static int |
251 | process_fork_event(event_t *event, unsigned long offset, unsigned long head) | ||
252 | { | ||
253 | struct thread *thread = threads__findnew(event->fork.pid); | ||
254 | struct thread *parent = threads__findnew(event->fork.ppid); | ||
255 | |||
256 | dump_printf("%p [%p]: PERF_RECORD_FORK: %d:%d\n", | ||
257 | (void *)(offset + head), | ||
258 | (void *)(long)(event->header.size), | ||
259 | event->fork.pid, event->fork.ppid); | ||
260 | |||
261 | /* | ||
262 | * A thread clone will have the same PID for both | ||
263 | * parent and child. | ||
264 | */ | ||
265 | if (thread == parent) | ||
266 | return 0; | ||
267 | |||
268 | if (!thread || !parent || thread__fork(thread, parent)) { | ||
269 | dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); | ||
270 | return -1; | ||
271 | } | ||
272 | total_fork++; | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static int | ||
278 | process_event(event_t *event, unsigned long offset, unsigned long head) | 229 | process_event(event_t *event, unsigned long offset, unsigned long head) |
279 | { | 230 | { |
280 | switch (event->header.type) { | 231 | switch (event->header.type) { |
@@ -288,7 +239,7 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
288 | return process_comm_event(event, offset, head); | 239 | return process_comm_event(event, offset, head); |
289 | 240 | ||
290 | case PERF_RECORD_FORK: | 241 | case PERF_RECORD_FORK: |
291 | return process_fork_event(event, offset, head); | 242 | return process_task_event(event, offset, head); |
292 | /* | 243 | /* |
293 | * We dont process them right now but they are fine: | 244 | * We dont process them right now but they are fine: |
294 | */ | 245 | */ |
@@ -638,11 +589,6 @@ static int __cmd_annotate(void) | |||
638 | exit(0); | 589 | exit(0); |
639 | } | 590 | } |
640 | 591 | ||
641 | if (kernel_maps__init(vmlinux_name, true, use_modules) < 0) { | ||
642 | pr_err("failed to create kernel maps for symbol resolution\b"); | ||
643 | return -1; | ||
644 | } | ||
645 | |||
646 | remap: | 592 | remap: |
647 | buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, | 593 | buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, |
648 | MAP_SHARED, input, offset); | 594 | MAP_SHARED, input, offset); |
@@ -743,8 +689,9 @@ static const struct option options[] = { | |||
743 | "be more verbose (show symbol address, etc)"), | 689 | "be more verbose (show symbol address, etc)"), |
744 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 690 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
745 | "dump raw trace in ASCII"), | 691 | "dump raw trace in ASCII"), |
746 | OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"), | 692 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
747 | OPT_BOOLEAN('m', "modules", &use_modules, | 693 | "file", "vmlinux pathname"), |
694 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, | ||
748 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | 695 | "load module symbols - WARNING: use only with -k and LIVE kernel"), |
749 | OPT_BOOLEAN('l', "print-line", &print_line, | 696 | OPT_BOOLEAN('l', "print-line", &print_line, |
750 | "print matching source lines (may be slow)"), | 697 | "print matching source lines (may be slow)"), |
@@ -770,7 +717,8 @@ static void setup_sorting(void) | |||
770 | 717 | ||
771 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) | 718 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) |
772 | { | 719 | { |
773 | symbol__init(sizeof(struct sym_priv)); | 720 | if (symbol__init(&symbol_conf) < 0) |
721 | return -1; | ||
774 | 722 | ||
775 | page_size = getpagesize(); | 723 | page_size = getpagesize(); |
776 | 724 | ||