aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r--tools/perf/builtin-trace.c97
1 files changed, 93 insertions, 4 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 407041d20de..dddf3f01b5a 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -11,6 +11,8 @@
11 11
12static char const *script_name; 12static char const *script_name;
13static char const *generate_script_lang; 13static char const *generate_script_lang;
14static bool debug_ordering;
15static u64 last_timestamp;
14 16
15static int default_start_script(const char *script __unused, 17static int default_start_script(const char *script __unused,
16 int argc __unused, 18 int argc __unused,
@@ -51,6 +53,8 @@ static void setup_scripting(void)
51 53
52static int cleanup_scripting(void) 54static int cleanup_scripting(void)
53{ 55{
56 pr_debug("\nperf trace script stopped\n");
57
54 return scripting_ops->stop_script(); 58 return scripting_ops->stop_script();
55} 59}
56 60
@@ -87,6 +91,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
87 } 91 }
88 92
89 if (session->sample_type & PERF_SAMPLE_RAW) { 93 if (session->sample_type & PERF_SAMPLE_RAW) {
94 if (debug_ordering) {
95 if (data.time < last_timestamp) {
96 pr_err("Samples misordered, previous: %llu "
97 "this: %llu\n", last_timestamp,
98 data.time);
99 }
100 last_timestamp = data.time;
101 }
90 /* 102 /*
91 * FIXME: better resolve from pid from the struct trace_entry 103 * FIXME: better resolve from pid from the struct trace_entry
92 * field, although it should be the same than this perf 104 * field, although it should be the same than this perf
@@ -97,17 +109,31 @@ static int process_sample_event(event_t *event, struct perf_session *session)
97 data.time, thread->comm); 109 data.time, thread->comm);
98 } 110 }
99 111
100 session->events_stats.total += data.period; 112 session->hists.stats.total_period += data.period;
101 return 0; 113 return 0;
102} 114}
103 115
104static struct perf_event_ops event_ops = { 116static struct perf_event_ops event_ops = {
105 .sample = process_sample_event, 117 .sample = process_sample_event,
106 .comm = event__process_comm, 118 .comm = event__process_comm,
119 .attr = event__process_attr,
120 .event_type = event__process_event_type,
121 .tracing_data = event__process_tracing_data,
122 .build_id = event__process_build_id,
123 .ordered_samples = true,
107}; 124};
108 125
126extern volatile int session_done;
127
128static void sig_handler(int sig __unused)
129{
130 session_done = 1;
131}
132
109static int __cmd_trace(struct perf_session *session) 133static int __cmd_trace(struct perf_session *session)
110{ 134{
135 signal(SIGINT, sig_handler);
136
111 return perf_session__process_events(session, &event_ops); 137 return perf_session__process_events(session, &event_ops);
112} 138}
113 139
@@ -505,7 +531,7 @@ static const char * const trace_usage[] = {
505static const struct option options[] = { 531static const struct option options[] = {
506 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 532 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
507 "dump raw trace in ASCII"), 533 "dump raw trace in ASCII"),
508 OPT_BOOLEAN('v', "verbose", &verbose, 534 OPT_INCR('v', "verbose", &verbose,
509 "be more verbose (show symbol address, etc)"), 535 "be more verbose (show symbol address, etc)"),
510 OPT_BOOLEAN('L', "Latency", &latency_format, 536 OPT_BOOLEAN('L', "Latency", &latency_format,
511 "show latency attributes (irqs/preemption disabled, etc)"), 537 "show latency attributes (irqs/preemption disabled, etc)"),
@@ -518,6 +544,8 @@ static const struct option options[] = {
518 "generate perf-trace.xx script in specified language"), 544 "generate perf-trace.xx script in specified language"),
519 OPT_STRING('i', "input", &input_name, "file", 545 OPT_STRING('i', "input", &input_name, "file",
520 "input file name"), 546 "input file name"),
547 OPT_BOOLEAN('d', "debug-ordering", &debug_ordering,
548 "check that samples time ordering is monotonic"),
521 549
522 OPT_END() 550 OPT_END()
523}; 551};
@@ -548,6 +576,65 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
548 suffix = REPORT_SUFFIX; 576 suffix = REPORT_SUFFIX;
549 } 577 }
550 578
579 if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) {
580 char *record_script_path, *report_script_path;
581 int live_pipe[2];
582 pid_t pid;
583
584 record_script_path = get_script_path(argv[1], RECORD_SUFFIX);
585 if (!record_script_path) {
586 fprintf(stderr, "record script not found\n");
587 return -1;
588 }
589
590 report_script_path = get_script_path(argv[1], REPORT_SUFFIX);
591 if (!report_script_path) {
592 fprintf(stderr, "report script not found\n");
593 return -1;
594 }
595
596 if (pipe(live_pipe) < 0) {
597 perror("failed to create pipe");
598 exit(-1);
599 }
600
601 pid = fork();
602 if (pid < 0) {
603 perror("failed to fork");
604 exit(-1);
605 }
606
607 if (!pid) {
608 dup2(live_pipe[1], 1);
609 close(live_pipe[0]);
610
611 __argv = malloc(5 * sizeof(const char *));
612 __argv[0] = "/bin/sh";
613 __argv[1] = record_script_path;
614 __argv[2] = "-o";
615 __argv[3] = "-";
616 __argv[4] = NULL;
617
618 execvp("/bin/sh", (char **)__argv);
619 exit(-1);
620 }
621
622 dup2(live_pipe[0], 0);
623 close(live_pipe[1]);
624
625 __argv = malloc((argc + 3) * sizeof(const char *));
626 __argv[0] = "/bin/sh";
627 __argv[1] = report_script_path;
628 for (i = 2; i < argc; i++)
629 __argv[i] = argv[i];
630 __argv[i++] = "-i";
631 __argv[i++] = "-";
632 __argv[i++] = NULL;
633
634 execvp("/bin/sh", (char **)__argv);
635 exit(-1);
636 }
637
551 if (suffix) { 638 if (suffix) {
552 script_path = get_script_path(argv[2], suffix); 639 script_path = get_script_path(argv[2], suffix);
553 if (!script_path) { 640 if (!script_path) {
@@ -576,11 +663,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
576 if (!script_name) 663 if (!script_name)
577 setup_pager(); 664 setup_pager();
578 665
579 session = perf_session__new(input_name, O_RDONLY, 0); 666 session = perf_session__new(input_name, O_RDONLY, 0, false);
580 if (session == NULL) 667 if (session == NULL)
581 return -ENOMEM; 668 return -ENOMEM;
582 669
583 if (!perf_session__has_traces(session, "record -R")) 670 if (strcmp(input_name, "-") &&
671 !perf_session__has_traces(session, "record -R"))
584 return -EINVAL; 672 return -EINVAL;
585 673
586 if (generate_script_lang) { 674 if (generate_script_lang) {
@@ -617,6 +705,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
617 err = scripting_ops->start_script(script_name, argc, argv); 705 err = scripting_ops->start_script(script_name, argc, argv);
618 if (err) 706 if (err)
619 goto out; 707 goto out;
708 pr_debug("perf trace started with script %s\n\n", script_name);
620 } 709 }
621 710
622 err = __cmd_trace(session); 711 err = __cmd_trace(session);