diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 124 |
1 files changed, 66 insertions, 58 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 9b393e7dca6f..bb788c109fe6 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -170,7 +170,8 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
170 | union perf_event *event, | 170 | union perf_event *event, |
171 | pid_t pid, pid_t tgid, | 171 | pid_t pid, pid_t tgid, |
172 | perf_event__handler_t process, | 172 | perf_event__handler_t process, |
173 | struct machine *machine) | 173 | struct machine *machine, |
174 | bool mmap_data) | ||
174 | { | 175 | { |
175 | char filename[PATH_MAX]; | 176 | char filename[PATH_MAX]; |
176 | FILE *fp; | 177 | FILE *fp; |
@@ -187,18 +188,13 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
187 | return -1; | 188 | return -1; |
188 | } | 189 | } |
189 | 190 | ||
190 | event->header.type = PERF_RECORD_MMAP2; | 191 | event->header.type = PERF_RECORD_MMAP; |
191 | /* | ||
192 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | ||
193 | */ | ||
194 | event->header.misc = PERF_RECORD_MISC_USER; | ||
195 | 192 | ||
196 | while (1) { | 193 | while (1) { |
197 | char bf[BUFSIZ]; | 194 | char bf[BUFSIZ]; |
198 | char prot[5]; | 195 | char prot[5]; |
199 | char execname[PATH_MAX]; | 196 | char execname[PATH_MAX]; |
200 | char anonstr[] = "//anon"; | 197 | char anonstr[] = "//anon"; |
201 | unsigned int ino; | ||
202 | size_t size; | 198 | size_t size; |
203 | ssize_t n; | 199 | ssize_t n; |
204 | 200 | ||
@@ -209,33 +205,40 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
209 | strcpy(execname, ""); | 205 | strcpy(execname, ""); |
210 | 206 | ||
211 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ | 207 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ |
212 | n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", | 208 | n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", |
213 | &event->mmap2.start, &event->mmap2.len, prot, | 209 | &event->mmap.start, &event->mmap.len, prot, |
214 | &event->mmap2.pgoff, &event->mmap2.maj, | 210 | &event->mmap.pgoff, |
215 | &event->mmap2.min, | 211 | execname); |
216 | &ino, execname); | 212 | /* |
217 | 213 | * Anon maps don't have the execname. | |
218 | event->mmap2.ino = (u64)ino; | 214 | */ |
219 | 215 | if (n < 4) | |
220 | if (n != 8) | ||
221 | continue; | 216 | continue; |
217 | /* | ||
218 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | ||
219 | */ | ||
220 | event->header.misc = PERF_RECORD_MISC_USER; | ||
222 | 221 | ||
223 | if (prot[2] != 'x') | 222 | if (prot[2] != 'x') { |
224 | continue; | 223 | if (!mmap_data || prot[0] != 'r') |
224 | continue; | ||
225 | |||
226 | event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; | ||
227 | } | ||
225 | 228 | ||
226 | if (!strcmp(execname, "")) | 229 | if (!strcmp(execname, "")) |
227 | strcpy(execname, anonstr); | 230 | strcpy(execname, anonstr); |
228 | 231 | ||
229 | size = strlen(execname) + 1; | 232 | size = strlen(execname) + 1; |
230 | memcpy(event->mmap2.filename, execname, size); | 233 | memcpy(event->mmap.filename, execname, size); |
231 | size = PERF_ALIGN(size, sizeof(u64)); | 234 | size = PERF_ALIGN(size, sizeof(u64)); |
232 | event->mmap2.len -= event->mmap.start; | 235 | event->mmap.len -= event->mmap.start; |
233 | event->mmap2.header.size = (sizeof(event->mmap2) - | 236 | event->mmap.header.size = (sizeof(event->mmap) - |
234 | (sizeof(event->mmap2.filename) - size)); | 237 | (sizeof(event->mmap.filename) - size)); |
235 | memset(event->mmap2.filename + size, 0, machine->id_hdr_size); | 238 | memset(event->mmap.filename + size, 0, machine->id_hdr_size); |
236 | event->mmap2.header.size += machine->id_hdr_size; | 239 | event->mmap.header.size += machine->id_hdr_size; |
237 | event->mmap2.pid = tgid; | 240 | event->mmap.pid = tgid; |
238 | event->mmap2.tid = pid; | 241 | event->mmap.tid = pid; |
239 | 242 | ||
240 | if (process(tool, event, &synth_sample, machine) != 0) { | 243 | if (process(tool, event, &synth_sample, machine) != 0) { |
241 | rc = -1; | 244 | rc = -1; |
@@ -308,20 +311,21 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
308 | pid_t pid, int full, | 311 | pid_t pid, int full, |
309 | perf_event__handler_t process, | 312 | perf_event__handler_t process, |
310 | struct perf_tool *tool, | 313 | struct perf_tool *tool, |
311 | struct machine *machine) | 314 | struct machine *machine, bool mmap_data) |
312 | { | 315 | { |
313 | pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full, | 316 | pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full, |
314 | process, machine); | 317 | process, machine); |
315 | if (tgid == -1) | 318 | if (tgid == -1) |
316 | return -1; | 319 | return -1; |
317 | return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, | 320 | return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, |
318 | process, machine); | 321 | process, machine, mmap_data); |
319 | } | 322 | } |
320 | 323 | ||
321 | int perf_event__synthesize_thread_map(struct perf_tool *tool, | 324 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
322 | struct thread_map *threads, | 325 | struct thread_map *threads, |
323 | perf_event__handler_t process, | 326 | perf_event__handler_t process, |
324 | struct machine *machine) | 327 | struct machine *machine, |
328 | bool mmap_data) | ||
325 | { | 329 | { |
326 | union perf_event *comm_event, *mmap_event; | 330 | union perf_event *comm_event, *mmap_event; |
327 | int err = -1, thread, j; | 331 | int err = -1, thread, j; |
@@ -338,7 +342,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, | |||
338 | for (thread = 0; thread < threads->nr; ++thread) { | 342 | for (thread = 0; thread < threads->nr; ++thread) { |
339 | if (__event__synthesize_thread(comm_event, mmap_event, | 343 | if (__event__synthesize_thread(comm_event, mmap_event, |
340 | threads->map[thread], 0, | 344 | threads->map[thread], 0, |
341 | process, tool, machine)) { | 345 | process, tool, machine, |
346 | mmap_data)) { | ||
342 | err = -1; | 347 | err = -1; |
343 | break; | 348 | break; |
344 | } | 349 | } |
@@ -360,10 +365,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, | |||
360 | 365 | ||
361 | /* if not, generate events for it */ | 366 | /* if not, generate events for it */ |
362 | if (need_leader && | 367 | if (need_leader && |
363 | __event__synthesize_thread(comm_event, | 368 | __event__synthesize_thread(comm_event, mmap_event, |
364 | mmap_event, | 369 | comm_event->comm.pid, 0, |
365 | comm_event->comm.pid, 0, | 370 | process, tool, machine, |
366 | process, tool, machine)) { | 371 | mmap_data)) { |
367 | err = -1; | 372 | err = -1; |
368 | break; | 373 | break; |
369 | } | 374 | } |
@@ -378,7 +383,7 @@ out: | |||
378 | 383 | ||
379 | int perf_event__synthesize_threads(struct perf_tool *tool, | 384 | int perf_event__synthesize_threads(struct perf_tool *tool, |
380 | perf_event__handler_t process, | 385 | perf_event__handler_t process, |
381 | struct machine *machine) | 386 | struct machine *machine, bool mmap_data) |
382 | { | 387 | { |
383 | DIR *proc; | 388 | DIR *proc; |
384 | struct dirent dirent, *next; | 389 | struct dirent dirent, *next; |
@@ -408,7 +413,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
408 | * one thread couldn't be synthesized. | 413 | * one thread couldn't be synthesized. |
409 | */ | 414 | */ |
410 | __event__synthesize_thread(comm_event, mmap_event, pid, 1, | 415 | __event__synthesize_thread(comm_event, mmap_event, pid, 1, |
411 | process, tool, machine); | 416 | process, tool, machine, mmap_data); |
412 | } | 417 | } |
413 | 418 | ||
414 | err = 0; | 419 | err = 0; |
@@ -516,52 +521,55 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp) | |||
516 | 521 | ||
517 | int perf_event__process_comm(struct perf_tool *tool __maybe_unused, | 522 | int perf_event__process_comm(struct perf_tool *tool __maybe_unused, |
518 | union perf_event *event, | 523 | union perf_event *event, |
519 | struct perf_sample *sample __maybe_unused, | 524 | struct perf_sample *sample, |
520 | struct machine *machine) | 525 | struct machine *machine) |
521 | { | 526 | { |
522 | return machine__process_comm_event(machine, event); | 527 | return machine__process_comm_event(machine, event, sample); |
523 | } | 528 | } |
524 | 529 | ||
525 | int perf_event__process_lost(struct perf_tool *tool __maybe_unused, | 530 | int perf_event__process_lost(struct perf_tool *tool __maybe_unused, |
526 | union perf_event *event, | 531 | union perf_event *event, |
527 | struct perf_sample *sample __maybe_unused, | 532 | struct perf_sample *sample, |
528 | struct machine *machine) | 533 | struct machine *machine) |
529 | { | 534 | { |
530 | return machine__process_lost_event(machine, event); | 535 | return machine__process_lost_event(machine, event, sample); |
531 | } | 536 | } |
532 | 537 | ||
533 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) | 538 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) |
534 | { | 539 | { |
535 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", | 540 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", |
536 | event->mmap.pid, event->mmap.tid, event->mmap.start, | 541 | event->mmap.pid, event->mmap.tid, event->mmap.start, |
537 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | 542 | event->mmap.len, event->mmap.pgoff, |
543 | (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', | ||
544 | event->mmap.filename); | ||
538 | } | 545 | } |
539 | 546 | ||
540 | size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) | 547 | size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) |
541 | { | 548 | { |
542 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 | 549 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 |
543 | " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n", | 550 | " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n", |
544 | event->mmap2.pid, event->mmap2.tid, event->mmap2.start, | 551 | event->mmap2.pid, event->mmap2.tid, event->mmap2.start, |
545 | event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, | 552 | event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, |
546 | event->mmap2.min, event->mmap2.ino, | 553 | event->mmap2.min, event->mmap2.ino, |
547 | event->mmap2.ino_generation, | 554 | event->mmap2.ino_generation, |
555 | (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', | ||
548 | event->mmap2.filename); | 556 | event->mmap2.filename); |
549 | } | 557 | } |
550 | 558 | ||
551 | int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, | 559 | int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, |
552 | union perf_event *event, | 560 | union perf_event *event, |
553 | struct perf_sample *sample __maybe_unused, | 561 | struct perf_sample *sample, |
554 | struct machine *machine) | 562 | struct machine *machine) |
555 | { | 563 | { |
556 | return machine__process_mmap_event(machine, event); | 564 | return machine__process_mmap_event(machine, event, sample); |
557 | } | 565 | } |
558 | 566 | ||
559 | int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, | 567 | int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, |
560 | union perf_event *event, | 568 | union perf_event *event, |
561 | struct perf_sample *sample __maybe_unused, | 569 | struct perf_sample *sample, |
562 | struct machine *machine) | 570 | struct machine *machine) |
563 | { | 571 | { |
564 | return machine__process_mmap2_event(machine, event); | 572 | return machine__process_mmap2_event(machine, event, sample); |
565 | } | 573 | } |
566 | 574 | ||
567 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) | 575 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) |
@@ -573,18 +581,18 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) | |||
573 | 581 | ||
574 | int perf_event__process_fork(struct perf_tool *tool __maybe_unused, | 582 | int perf_event__process_fork(struct perf_tool *tool __maybe_unused, |
575 | union perf_event *event, | 583 | union perf_event *event, |
576 | struct perf_sample *sample __maybe_unused, | 584 | struct perf_sample *sample, |
577 | struct machine *machine) | 585 | struct machine *machine) |
578 | { | 586 | { |
579 | return machine__process_fork_event(machine, event); | 587 | return machine__process_fork_event(machine, event, sample); |
580 | } | 588 | } |
581 | 589 | ||
582 | int perf_event__process_exit(struct perf_tool *tool __maybe_unused, | 590 | int perf_event__process_exit(struct perf_tool *tool __maybe_unused, |
583 | union perf_event *event, | 591 | union perf_event *event, |
584 | struct perf_sample *sample __maybe_unused, | 592 | struct perf_sample *sample, |
585 | struct machine *machine) | 593 | struct machine *machine) |
586 | { | 594 | { |
587 | return machine__process_exit_event(machine, event); | 595 | return machine__process_exit_event(machine, event, sample); |
588 | } | 596 | } |
589 | 597 | ||
590 | size_t perf_event__fprintf(union perf_event *event, FILE *fp) | 598 | size_t perf_event__fprintf(union perf_event *event, FILE *fp) |
@@ -615,21 +623,21 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) | |||
615 | 623 | ||
616 | int perf_event__process(struct perf_tool *tool __maybe_unused, | 624 | int perf_event__process(struct perf_tool *tool __maybe_unused, |
617 | union perf_event *event, | 625 | union perf_event *event, |
618 | struct perf_sample *sample __maybe_unused, | 626 | struct perf_sample *sample, |
619 | struct machine *machine) | 627 | struct machine *machine) |
620 | { | 628 | { |
621 | return machine__process_event(machine, event); | 629 | return machine__process_event(machine, event, sample); |
622 | } | 630 | } |
623 | 631 | ||
624 | void thread__find_addr_map(struct thread *self, | 632 | void thread__find_addr_map(struct thread *thread, |
625 | struct machine *machine, u8 cpumode, | 633 | struct machine *machine, u8 cpumode, |
626 | enum map_type type, u64 addr, | 634 | enum map_type type, u64 addr, |
627 | struct addr_location *al) | 635 | struct addr_location *al) |
628 | { | 636 | { |
629 | struct map_groups *mg = &self->mg; | 637 | struct map_groups *mg = &thread->mg; |
630 | bool load_map = false; | 638 | bool load_map = false; |
631 | 639 | ||
632 | al->thread = self; | 640 | al->thread = thread; |
633 | al->addr = addr; | 641 | al->addr = addr; |
634 | al->cpumode = cpumode; | 642 | al->cpumode = cpumode; |
635 | al->filtered = false; | 643 | al->filtered = false; |
@@ -725,10 +733,10 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
725 | return -1; | 733 | return -1; |
726 | 734 | ||
727 | if (symbol_conf.comm_list && | 735 | if (symbol_conf.comm_list && |
728 | !strlist__has_entry(symbol_conf.comm_list, thread->comm)) | 736 | !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) |
729 | goto out_filtered; | 737 | goto out_filtered; |
730 | 738 | ||
731 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid); | 739 | dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); |
732 | /* | 740 | /* |
733 | * Have we already created the kernel maps for this machine? | 741 | * Have we already created the kernel maps for this machine? |
734 | * | 742 | * |