aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c124
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
321int perf_event__synthesize_thread_map(struct perf_tool *tool, 324int 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
379int perf_event__synthesize_threads(struct perf_tool *tool, 384int 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
517int perf_event__process_comm(struct perf_tool *tool __maybe_unused, 522int 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
525int perf_event__process_lost(struct perf_tool *tool __maybe_unused, 530int 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
533size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 538size_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
540size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) 547size_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
551int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, 559int 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
559int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, 567int 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
567size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 575size_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
574int perf_event__process_fork(struct perf_tool *tool __maybe_unused, 582int 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
582int perf_event__process_exit(struct perf_tool *tool __maybe_unused, 590int 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
590size_t perf_event__fprintf(union perf_event *event, FILE *fp) 598size_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
616int perf_event__process(struct perf_tool *tool __maybe_unused, 624int 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
624void thread__find_addr_map(struct thread *self, 632void 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 *