Commit fc36f948 authored by Stephane Eranian's avatar Stephane Eranian Committed by Arnaldo Carvalho de Melo

perf script: Enable printing of interrupted machine state

This patch adds the output of the interrupted machine state (iregs) to
perf script. It presents them  as NAME:VALUE so this is easy to parse
during post processing.

To capture the interrupted machine state:
   $ perf record -I ....

to display iregs, use the -F option:

   $ perf script -F ip,iregs
   40afc2   AX:0x6c5770    BX:0x1e    CX:0x5f4d80a    DX:0x101010101010101    SI:0x1
Signed-off-by: default avatarStephane Eranian <eranian@google.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1441039273-16260-2-git-send-email-eranian@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d988d5ee
...@@ -116,7 +116,7 @@ OPTIONS ...@@ -116,7 +116,7 @@ OPTIONS
--fields:: --fields::
Comma separated list of fields to print. Options are: Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
srcline, period, flags. srcline, period, iregs, flags.
Field list can be prepended with the type, trace, sw or hw, Field list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies. to indicate to which event type the field list applies.
e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "util/exec_cmd.h" #include "util/exec_cmd.h"
#include "util/header.h" #include "util/header.h"
#include "util/parse-options.h" #include "util/parse-options.h"
#include "util/perf_regs.h"
#include "util/session.h" #include "util/session.h"
#include "util/tool.h" #include "util/tool.h"
#include "util/symbol.h" #include "util/symbol.h"
...@@ -46,6 +47,7 @@ enum perf_output_field { ...@@ -46,6 +47,7 @@ enum perf_output_field {
PERF_OUTPUT_SYMOFFSET = 1U << 11, PERF_OUTPUT_SYMOFFSET = 1U << 11,
PERF_OUTPUT_SRCLINE = 1U << 12, PERF_OUTPUT_SRCLINE = 1U << 12,
PERF_OUTPUT_PERIOD = 1U << 13, PERF_OUTPUT_PERIOD = 1U << 13,
PERF_OUTPUT_IREGS = 1U << 14,
}; };
struct output_option { struct output_option {
...@@ -66,6 +68,7 @@ struct output_option { ...@@ -66,6 +68,7 @@ struct output_option {
{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
{.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
{.str = "period", .field = PERF_OUTPUT_PERIOD}, {.str = "period", .field = PERF_OUTPUT_PERIOD},
{.str = "iregs", .field = PERF_OUTPUT_IREGS},
}; };
/* default set to maintain compatibility with current format */ /* default set to maintain compatibility with current format */
...@@ -255,6 +258,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, ...@@ -255,6 +258,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
PERF_OUTPUT_PERIOD)) PERF_OUTPUT_PERIOD))
return -EINVAL; return -EINVAL;
if (PRINT_FIELD(IREGS) &&
perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
PERF_OUTPUT_IREGS))
return -EINVAL;
return 0; return 0;
} }
...@@ -352,6 +360,24 @@ static int perf_session__check_output_opt(struct perf_session *session) ...@@ -352,6 +360,24 @@ static int perf_session__check_output_opt(struct perf_session *session)
return 0; return 0;
} }
static void print_sample_iregs(union perf_event *event __maybe_unused,
struct perf_sample *sample,
struct thread *thread __maybe_unused,
struct perf_event_attr *attr)
{
struct regs_dump *regs = &sample->intr_regs;
uint64_t mask = attr->sample_regs_intr;
unsigned i = 0, r;
if (!regs)
return;
for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++];
printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
}
}
static void print_sample_start(struct perf_sample *sample, static void print_sample_start(struct perf_sample *sample,
struct thread *thread, struct thread *thread,
struct perf_evsel *evsel) struct perf_evsel *evsel)
...@@ -525,6 +551,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample, ...@@ -525,6 +551,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
PERF_MAX_STACK_DEPTH); PERF_MAX_STACK_DEPTH);
} }
if (PRINT_FIELD(IREGS))
print_sample_iregs(event, sample, thread, attr);
printf("\n"); printf("\n");
} }
...@@ -1643,7 +1672,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1643,7 +1672,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
"comma separated output fields prepend with 'type:'. " "comma separated output fields prepend with 'type:'. "
"Valid types: hw,sw,trace,raw. " "Valid types: hw,sw,trace,raw. "
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
"addr,symoff,period,flags", parse_output_fields), "addr,symoff,period,iregs,flags", parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide, OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"), "system-wide collection from all CPUs"),
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment