From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx> Add the options to trace-cmd report to show the timestamp of the first and last events. This also fixes a memory leak when --cpus is used, but was not a major issue as the code exited immediately afterward. Suggested-by: Julia Lawall <julia.lawall@xxxxxxxx> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216068 Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> --- .../trace-cmd/trace-cmd-report.1.txt | 6 ++ tracecmd/trace-read.c | 56 +++++++++++++++++-- tracecmd/trace-usage.c | 2 + 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Documentation/trace-cmd/trace-cmd-report.1.txt b/Documentation/trace-cmd/trace-cmd-report.1.txt index ccf635fb664b..d517a4a6c766 100644 --- a/Documentation/trace-cmd/trace-cmd-report.1.txt +++ b/Documentation/trace-cmd/trace-cmd-report.1.txt @@ -285,6 +285,12 @@ OPTIONS *--cpus*:: List the CPUs that have data in the trace file then exit. +*--first-event*:: + Show the timestamp of the first event of all CPUs that have data. + +*--last-event*:: + Show the timestamp of the last event of all CPUs that have data. + *--stat*:: If the trace.dat file recorded the final stats (outputed at the end of record) the *--stat* option can be used to retrieve them. diff --git a/tracecmd/trace-read.c b/tracecmd/trace-read.c index df559d2af47e..691450b05a39 100644 --- a/tracecmd/trace-read.c +++ b/tracecmd/trace-read.c @@ -157,7 +157,8 @@ static void print_event_name(struct trace_seq *s, struct tep_event *event) enum time_fmt { TIME_FMT_LAT = 1, - TIME_FMT_NORMAL = 2, + TIME_FMT_NORMAL, + TIME_FMT_TS, }; static const char *time_format(struct tracecmd_input *handle, enum time_fmt tf) @@ -172,11 +173,11 @@ static const char *time_format(struct tracecmd_input *handle, enum time_fmt tf) default: if (tracecmd_get_flags(handle) & TRACECMD_FL_IN_USECS) { if (tep_test_flag(tep, TEP_NSEC_OUTPUT)) - return " %9.1d:"; + return tf == TIME_FMT_NORMAL ? " %9.1d:" : "%9.1d"; else - return " %6.1000d:"; + return tf == TIME_FMT_NORMAL ? " %6.1000d:" : "%6.1000d"; } else - return "%12d:"; + return tf == TIME_FMT_NORMAL ? "%12d:" : "%12d"; } } @@ -1507,6 +1508,19 @@ static void set_event_flags(struct tep_handle *pevent, struct event_str *list, } } +static void show_event_ts(struct tracecmd_input *handle, + struct tep_record *record) +{ + const char *tfmt = time_format(handle, TIME_FMT_TS); + struct tep_handle *tep = tracecmd_get_tep(handle); + struct trace_seq s; + + trace_seq_init(&s); + tep_print_event(tep, &s, record, tfmt, TEP_PRINT_TIME); + printf("%s", s.buffer); + trace_seq_destroy(&s); +} + static void add_hook(const char *arg) { struct hook_list *hook; @@ -1543,6 +1557,8 @@ enum { OPT_events = 254, OPT_cpu = 255, OPT_cpus = 256, + OPT_first = 257, + OPT_last = 258, }; void trace_report (int argc, char **argv) @@ -1571,6 +1587,8 @@ void trace_report (int argc, char **argv) int show_version = 0; int show_events = 0; int show_cpus = 0; + int show_first = 0; + int show_last = 0; int print_events = 0; int nanosec = 0; int no_date = 0; @@ -1601,6 +1619,7 @@ void trace_report (int argc, char **argv) {"events", no_argument, NULL, OPT_events}, {"event", required_argument, NULL, OPT_event}, {"filter-test", no_argument, NULL, 'T'}, + {"first-event", no_argument, NULL, OPT_first}, {"kallsyms", required_argument, NULL, OPT_kallsyms}, {"pid", required_argument, NULL, OPT_pid}, {"comm", required_argument, NULL, OPT_comm}, @@ -1610,6 +1629,7 @@ void trace_report (int argc, char **argv) {"stat", no_argument, NULL, OPT_stat}, {"boundary", no_argument, NULL, OPT_boundary}, {"debug", no_argument, NULL, OPT_debug}, + {"last-event", no_argument, NULL, OPT_last}, {"profile", no_argument, NULL, OPT_profile}, {"uname", no_argument, NULL, OPT_uname}, {"version", no_argument, NULL, OPT_version}, @@ -1754,6 +1774,14 @@ void trace_report (int argc, char **argv) case OPT_stat: show_stat = 1; break; + case OPT_first: + show_first = 1; + show_cpus = 1; + break; + case OPT_last: + show_last = 1; + show_cpus = 1; + break; case OPT_boundary: /* Debug to look at buffer breaks */ buffer_breaks = 1; @@ -1923,6 +1951,7 @@ void trace_report (int argc, char **argv) } if (show_cpus) { + struct tep_record *record; int cpus; int ret; int i; @@ -1935,8 +1964,23 @@ void trace_report (int argc, char **argv) cpus = tracecmd_cpus(handle); printf("List of CPUs in %s with data:\n", inputs->file); for (i = 0; i < cpus; i++) { - if (tracecmd_read_cpu_first(handle, i)) - printf(" %d\n", i); + if ((record = tracecmd_read_cpu_first(handle, i))) { + printf(" %d", i); + if (show_first) { + printf("\tFirst event:"); + show_event_ts(handle, record); + } + if (show_last) { + tracecmd_free_record(record); + record = tracecmd_read_cpu_last(handle, i); + if (record) { + printf("\tLast event:"); + show_event_ts(handle, record); + } + } + tracecmd_free_record(record); + printf("\n"); + } } continue; } diff --git a/tracecmd/trace-usage.c b/tracecmd/trace-usage.c index 2cfa64f5aa0c..abf6c3ac5990 100644 --- a/tracecmd/trace-usage.c +++ b/tracecmd/trace-usage.c @@ -230,6 +230,8 @@ static struct usage_help usage_help[] = { " --cpu <cpu1,cpu2,...> - filter events according to the given cpu list.\n" " A range of CPUs can be specified using 'cpuX-cpuY' notation.\n" " --cpus - List the CPUs that have content in it then exit.\n" + " --first-event - Show the timestamp of the first event for all CPUs.\n" + " --last-event - Show the timestamp of the last event for all CPUs.\n" " --check-events return whether all event formats can be parsed\n" " --stat - show the buffer stats that were reported at the end of the record.\n" " --uname - show uname of the record, if it was saved\n" -- 2.35.1
![]() |