lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1508921599-10832-3-git-send-email-yuzhoujian@didichuxing.com>
Date:   Wed, 25 Oct 2017 16:53:19 +0800
From:   yuzhoujian <ufo19890607@...il.com>
To:     peterz@...radead.org, mingo@...hat.com,
        alexander.shishkin@...ux.intel.com, jolsa@...nel.org,
        dsahern@...il.com, namhyung@...nel.org, milian.wolff@...b.com,
        arnaldo.melo@...il.com, yuzhoujian@...ichuxing.com,
        adrian.hunter@...el.com, wangnan0@...wei.com
Cc:     linux-perf-users@...r.kernel.org, linux-kernel@...r.kernel.org,
        acme@...hat.com
Subject: [PATCH v5 2/2] Add the fp_selection_helper to set the fp for print functions

This patch will make all print functions receive the fp, add the fp_selection_helper
function to select the fp(stdout or the dump_event fp) and open the dump file for
all print functions. When the perf script is over, closes the dump_event file and
calculates its size.

Changes since v4:
- the fp_selection_helper will be invoked by process_event not process_sample_event
- replace some printf with fprintf in process_event

Changes since v3:
- free the evsel->priv by zfree()

Changes since v2:
- remove the file_name variable and get the data file name from struct perf_session
- remove the per_event_dump_file variable and get the dump_event fp from struct
 perf_evsel
- add the fp_selection_helper function to select the fp(stdout or the dump_event
 fp) and open the dump file for all print functions if evname and last evsel name is not
 the same.
- close the dump file for all the evsels and calculate the dump file's size at the end of
 the perf script.
- solve the segmentation fault generated by perf script --per-event-dump --show-mmap-events

Changes since v1:
- modify the dump file name to <ORIGINAL PERF DATA FILE NAME>-script-dump-<EVENT NAME>.txt
 ect. perf.data-script-dump-cycles.txt, perf.data-script-dump-cs.txt
- split the original patch(Make all those related functions receive the file pointer)
 to two patches, and this is the second part of the original one.

Signed-off-by: yuzhoujian <yuzhoujian@...ichuxing.com>
---
 tools/perf/builtin-script.c | 107 +++++++++++++++++++++++++++++++++++---------
 tools/perf/util/session.c   |  19 ++++++++
 2 files changed, 106 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 81f141f..8d98349 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1431,6 +1431,50 @@ static int data_src__fprintf(u64 data_src, FILE *fp)
 	return fprintf(fp, "%-*s", maxlen, out);
 }
 
+static FILE *fp_selection_helper(struct perf_script *script, struct perf_evsel *evsel)
+{
+	const char *evname;
+	char *filename;
+	FILE *fp;
+	struct perf_tool *tool = &script->tool;
+	struct perf_script_evsel *ps;
+
+	evname = perf_evsel__name(evsel);
+	if (tool->per_event_dump) {
+		ps = (struct perf_script_evsel *)evsel->priv;
+
+		/* if evname and last evsel name is not the same, opens another dump file. */
+		if (evname != tool->last_evsel_name) {
+			if (asprintf(&filename, "%s%s%s%s", script->session->file->path,
+				"-script-dump-", evname, ".txt") < 0)
+				BUG_ON("fail to add the suffix for dump file's name!\n");
+
+			fp = fopen(filename, "a+");
+			if (!fp)
+				BUG_ON("fail to open the dump file!\n");
+
+			if (!ps) {
+				ps = zalloc(sizeof(struct perf_script_evsel));
+				if (!ps)
+					BUG_ON("fail to create a perf_script_evsel struct!\n");
+				ps->samples = 0;
+			}
+			ps->filename = filename;
+			ps->dump_evsel_fp = fp;
+			tool->last_evsel_name = evname;
+			evsel->priv = ps;
+		} else {
+			if (ps->dump_evsel_fp)
+				fp = ps->dump_evsel_fp;
+			else
+				BUG_ON("fail to get the dump file's fp!\n");
+		}
+	} else {
+		fp = stdout;
+	}
+	return fp;
+}
+
 static void process_event(struct perf_script *script,
 			  struct perf_sample *sample, struct perf_evsel *evsel,
 			  struct addr_location *al,
@@ -1439,15 +1483,25 @@ static void process_event(struct perf_script *script,
 	struct thread *thread = al->thread;
 	struct perf_event_attr *attr = &evsel->attr;
 	unsigned int type = output_type(attr->type);
-	FILE *fp = stdout;
+	struct perf_script_evsel *ps;
+	struct perf_tool *tool = &script->tool;
+	FILE *fp;
+
+	fp = fp_selection_helper(script, evsel);
 
 	if (output[type].fields == 0)
 		return;
 
+	if (tool->per_event_dump) {
+		ps = (struct perf_script_evsel *)evsel->priv;
+		ps->samples++;
+		evsel->priv = ps;
+	}
+
 	perf_sample__fprintf_start(sample, thread, evsel, fp);
 
 	if (PRINT_FIELD(PERIOD))
-		printf("%10" PRIu64 " ", sample->period);
+		fprintf(fp, "%10" PRIu64 " ", sample->period);
 
 	if (PRINT_FIELD(EVNAME)) {
 		const char *evname = perf_evsel__name(evsel);
@@ -1455,7 +1509,7 @@ static void process_event(struct perf_script *script,
 		if (!script->name_width)
 			script->name_width = perf_evlist__max_name_len(script->session->evlist);
 
-		printf("%*s: ", script->name_width,
+		fprintf(fp, "%*s: ", script->name_width,
 		       evname ? evname : "[unknown]");
 	}
 
@@ -1513,8 +1567,8 @@ static void process_event(struct perf_script *script,
 	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
 
 	if (PRINT_FIELD(PHYS_ADDR))
-		printf("%16" PRIx64, sample->phys_addr);
-	printf("\n");
+		fprintf(fp, "%16" PRIx64, sample->phys_addr);
+	fprintf(fp, "\n");
 }
 
 static struct scripting_ops	*scripting_ops;
@@ -1671,6 +1725,7 @@ static int process_comm_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 	int ret = -1;
 
 	thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
@@ -1688,8 +1743,9 @@ static int process_comm_event(struct perf_tool *tool,
 		sample->tid = event->comm.tid;
 		sample->pid = event->comm.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	ret = 0;
 out:
 	thread__put(thread);
@@ -1705,6 +1761,7 @@ static int process_namespaces_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 	int ret = -1;
 
 	thread = machine__findnew_thread(machine, event->namespaces.pid,
@@ -1723,8 +1780,9 @@ static int process_namespaces_event(struct perf_tool *tool,
 		sample->tid = event->namespaces.tid;
 		sample->pid = event->namespaces.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	ret = 0;
 out:
 	thread__put(thread);
@@ -1740,6 +1798,7 @@ static int process_fork_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 
 	if (perf_event__process_fork(tool, event, sample, machine) < 0)
 		return -1;
@@ -1756,8 +1815,9 @@ static int process_fork_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 
 	return 0;
@@ -1772,6 +1832,7 @@ static int process_exit_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 
 	thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
 	if (thread == NULL) {
@@ -1785,8 +1846,9 @@ static int process_exit_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 
 	if (perf_event__process_exit(tool, event, sample, machine) < 0)
 		err = -1;
@@ -1804,6 +1866,7 @@ static int process_mmap_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 
 	if (perf_event__process_mmap(tool, event, sample, machine) < 0)
 		return -1;
@@ -1820,8 +1883,9 @@ static int process_mmap_event(struct perf_tool *tool,
 		sample->tid = event->mmap.tid;
 		sample->pid = event->mmap.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 	return 0;
 }
@@ -1835,6 +1899,7 @@ static int process_mmap2_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 
 	if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
 		return -1;
@@ -1851,8 +1916,9 @@ static int process_mmap2_event(struct perf_tool *tool,
 		sample->tid = event->mmap2.tid;
 		sample->pid = event->mmap2.pid;
 	}
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 	return 0;
 }
@@ -1866,6 +1932,7 @@ static int process_switch_event(struct perf_tool *tool,
 	struct perf_script *script = container_of(tool, struct perf_script, tool);
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	FILE *fp;
 
 	if (perf_event__process_switch(tool, event, sample, machine) < 0)
 		return -1;
@@ -1876,9 +1943,9 @@ static int process_switch_event(struct perf_tool *tool,
 		pr_debug("problem processing SWITCH event, skipping it.\n");
 		return -1;
 	}
-
-	perf_sample__fprintf_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	perf_sample__fprintf_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 	return 0;
 }
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b3fd62f..0a4784f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdio.h>
 
 #include "evlist.h"
 #include "evsel.h"
@@ -1828,6 +1830,9 @@ static int __perf_session__process_events(struct perf_session *session,
 {
 	struct ordered_events *oe = &session->ordered_events;
 	struct perf_tool *tool = session->tool;
+	struct perf_evlist *evlist = session->evlist;
+	struct perf_evsel *evsel;
+	struct perf_script_evsel *ps;
 	int fd = perf_data_file__fd(session->file);
 	u64 head, page_offset, file_offset, file_pos, size;
 	int err, mmap_prot, mmap_flags, map_idx = 0;
@@ -1835,6 +1840,7 @@ static int __perf_session__process_events(struct perf_session *session,
 	char *buf, *mmaps[NUM_MMAPS];
 	union perf_event *event;
 	struct ui_progress prog;
+	struct stat statbuf;
 	s64 skip;
 
 	perf_tool__fill_defaults(tool);
@@ -1940,6 +1946,19 @@ static int __perf_session__process_events(struct perf_session *session,
 	ordered_events__reinit(&session->ordered_events);
 	auxtrace__free_events(session);
 	session->one_mmap = false;
+	/* Closes the dump_event file and calculates its size at last. */
+	if (tool->per_event_dump) {
+		evlist__for_each_entry(evlist, evsel) {
+			ps = (struct perf_script_evsel *)evsel->priv;
+			if (!ps)
+				BUG_ON("fail to get the perf_script_evsel\n");
+			stat(ps->filename, &statbuf);
+			fprintf(stderr, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
+				statbuf.st_size / 1024.0 / 1024.0, ps->filename, ps->samples);
+			fclose(ps->dump_evsel_fp);
+			zfree(&evsel->priv);
+		}
+	}
 	return err;
 }
 
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ