|
@@ -1392,6 +1392,7 @@ struct perf_script {
|
|
bool show_switch_events;
|
|
bool show_switch_events;
|
|
bool show_namespace_events;
|
|
bool show_namespace_events;
|
|
bool allocated;
|
|
bool allocated;
|
|
|
|
+ bool per_event_dump;
|
|
struct cpu_map *cpus;
|
|
struct cpu_map *cpus;
|
|
struct thread_map *threads;
|
|
struct thread_map *threads;
|
|
int name_width;
|
|
int name_width;
|
|
@@ -1438,7 +1439,7 @@ static void process_event(struct perf_script *script,
|
|
struct thread *thread = al->thread;
|
|
struct thread *thread = al->thread;
|
|
struct perf_event_attr *attr = &evsel->attr;
|
|
struct perf_event_attr *attr = &evsel->attr;
|
|
unsigned int type = output_type(attr->type);
|
|
unsigned int type = output_type(attr->type);
|
|
- FILE *fp = stdout;
|
|
|
|
|
|
+ FILE *fp = evsel->priv;
|
|
|
|
|
|
if (output[type].fields == 0)
|
|
if (output[type].fields == 0)
|
|
return;
|
|
return;
|
|
@@ -1887,6 +1888,52 @@ static void sig_handler(int sig __maybe_unused)
|
|
session_done = 1;
|
|
session_done = 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void perf_script__fclose_per_event_dump(struct perf_script *script)
|
|
|
|
+{
|
|
|
|
+ struct perf_evlist *evlist = script->session->evlist;
|
|
|
|
+ struct perf_evsel *evsel;
|
|
|
|
+
|
|
|
|
+ evlist__for_each_entry(evlist, evsel) {
|
|
|
|
+ if (!evsel->priv)
|
|
|
|
+ break;
|
|
|
|
+ fclose(evsel->priv);
|
|
|
|
+ evsel->priv = NULL;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int perf_script__fopen_per_event_dump(struct perf_script *script)
|
|
|
|
+{
|
|
|
|
+ struct perf_evsel *evsel;
|
|
|
|
+
|
|
|
|
+ evlist__for_each_entry(script->session->evlist, evsel) {
|
|
|
|
+ char filename[PATH_MAX];
|
|
|
|
+ snprintf(filename, sizeof(filename), "%s.%s.dump",
|
|
|
|
+ script->session->file->path, perf_evsel__name(evsel));
|
|
|
|
+ evsel->priv = fopen(filename, "w");
|
|
|
|
+ if (evsel->priv == NULL)
|
|
|
|
+ goto out_err_fclose;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+out_err_fclose:
|
|
|
|
+ perf_script__fclose_per_event_dump(script);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int perf_script__setup_per_event_dump(struct perf_script *script)
|
|
|
|
+{
|
|
|
|
+ struct perf_evsel *evsel;
|
|
|
|
+
|
|
|
|
+ if (script->per_event_dump)
|
|
|
|
+ return perf_script__fopen_per_event_dump(script);
|
|
|
|
+
|
|
|
|
+ evlist__for_each_entry(script->session->evlist, evsel)
|
|
|
|
+ evsel->priv = stdout;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int __cmd_script(struct perf_script *script)
|
|
static int __cmd_script(struct perf_script *script)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
@@ -1908,8 +1955,16 @@ static int __cmd_script(struct perf_script *script)
|
|
if (script->show_namespace_events)
|
|
if (script->show_namespace_events)
|
|
script->tool.namespaces = process_namespaces_event;
|
|
script->tool.namespaces = process_namespaces_event;
|
|
|
|
|
|
|
|
+ if (perf_script__setup_per_event_dump(script)) {
|
|
|
|
+ pr_err("Couldn't create the per event dump files\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
ret = perf_session__process_events(script->session);
|
|
ret = perf_session__process_events(script->session);
|
|
|
|
|
|
|
|
+ if (script->per_event_dump)
|
|
|
|
+ perf_script__fclose_per_event_dump(script);
|
|
|
|
+
|
|
if (debug_mode)
|
|
if (debug_mode)
|
|
pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
|
|
pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
|
|
|
|
|
|
@@ -2827,6 +2882,8 @@ int cmd_script(int argc, const char **argv)
|
|
"Show context switch events (if recorded)"),
|
|
"Show context switch events (if recorded)"),
|
|
OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
|
|
OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
|
|
"Show namespace events (if recorded)"),
|
|
"Show namespace events (if recorded)"),
|
|
|
|
+ OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
|
|
|
|
+ "Dump trace output to files named by the monitored events"),
|
|
OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
|
|
OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
|
|
OPT_INTEGER(0, "max-blocks", &max_blocks,
|
|
OPT_INTEGER(0, "max-blocks", &max_blocks,
|
|
"Maximum number of code blocks to dump with brstackinsn"),
|
|
"Maximum number of code blocks to dump with brstackinsn"),
|