linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] perf script: Add script per-event-dump support
@ 2017-10-11 18:23 ufo19890607
  2017-10-11 18:23 ` [PATCH v3 1/4] Add two elements for perf_tool struct, and add three elements for perf_evsel struct, and add the per-event-dump option for perf script ufo19890607
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: ufo19890607 @ 2017-10-11 18:23 UTC (permalink / raw)
  To: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian
  Cc: linux-perf-users, linux-kernel

From: yuzhoujian <yuzhoujian@didichuxing.com>

Introduce a new option to print trace output to files named by the 
monitored events and update perf-script documentation accordingly.

Shown below is output of perf script command with the newly introduced
option.

         $perf record -e cycles -e cs -ag -- sleep 1
         $perf script --per-event-dump
	 [ perf script: Wrote 0.051 MB perf.data-script-dump-cycles.txt (76 samples) ]
	 [ perf script: Wrote 0.012 MB perf.data-script-dump-cs.txt (69 samples) ]
         $ls
         perf.data-script-dump-cycles.txt perf.data-script-dump-cs.txt

Without per-event-dump support, drawing flamegraphs for different events
would be a very troublesome thing. You can monitor only one event at a time 
if you want to get flamegraphs for different events. Using this option, you 
can get the trace output files named by the monitored events, and could draw 
flamegraphs according to the event's name.


yuzhoujian (4):
Patch 1: Add two elements for perf_tool struct, and add three elements for
    	perf_evsel struct, and add the per-event-dump option for perf script.
Patch 2: Add fp argument to print functions
Patch 3: Replace printf with fprintf for all print functions
Patch 4: Make all print functions receive the fp argument, open and close the
    	dump_event file for each evsel, and calculate the dump_event file's size.

Changes since v2:
- Patch 1: Add the last_evsel_name for per_tool struct and three elements for perf_evsel struct.
- Patch 2: None
- Patch 3: None
- Patch 4: Remove the file_name and per_event_dump_file variables. 
	   Add the fp_selection_helper function to select the fp and open the dump file 
 for all print functions.
 	   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: 
- Patch 1: Remove the set of script.tool.per_event_dump variable.
- Patch 2: Add the __maybe_unused attribute for the fp argument in the second patch.
- Patch 3: remove the fp_selection_helper function for setting the fp argument.
- Patch 2: split the original second patch(Makes all those related functions receive 
 the FILE pointer) to two patches.
- Patch 4: modify the file name of per-event-dump to 
 <ORIGINAL PERF DATA FILE NAME>-script-dump-<EVENT NAME>.txt

 tools/perf/builtin-script.c | 467 +++++++++++++++++++++++++-------------------
 tools/perf/util/evsel.h     |   4 +
 tools/perf/util/session.c   |  16 +-
 tools/perf/util/tool.h      |   3 +
 4 files changed, 286 insertions(+), 204 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/4] Add two elements for perf_tool struct, and add three elements for perf_evsel struct, and add the per-event-dump option for perf script
  2017-10-11 18:23 [PATCH v3 0/4] perf script: Add script per-event-dump support ufo19890607
@ 2017-10-11 18:23 ` ufo19890607
  2017-10-11 18:23 ` [PATCH v3 2/4] Add fp argument to print functions ufo19890607
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: ufo19890607 @ 2017-10-11 18:23 UTC (permalink / raw)
  To: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian
  Cc: linux-perf-users, linux-kernel

From: yuzhoujian <yuzhoujian@didichuxing.com>

This patch will add two elements for per_tool struct: per_event_dump
is used to mark the per-event-dump option, last_evsel_name is used
to save last evsel's name, and add three elements for perf_evsel struct:
dump_event_fp is used to save the file pointer of the dump_event file,
filename is used to save the file name of the dump_event file, samples
is used to save the number of samples for each evsel, and add the
OPT_BOOLEAN for per-event-dump in the perf_data_file struct.

Changes since v2:
- add the last_evsel_name for per_tool struct to save last evsel's name.
- add three elements for perf_evsel struct:dump_event_fp is used to save
 the file pointer of the dump_event file, filename is used to save the file
 name of the dump_event file, samples is used to save the number of samples
 for each evsel.

Changes since v1:
- remove the set for script.tool.per_event_dump variable,since the OPT_BOOLEAN
 will do the same thing.

Signed-off-by: yuzhoujian <yuzhoujian@didichuxing.com>
---
 tools/perf/builtin-script.c | 3 +++
 tools/perf/util/evsel.h     | 4 ++++
 tools/perf/util/tool.h      | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 7167df2..4ffa716 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2729,6 +2729,7 @@ int cmd_script(int argc, const char **argv)
 			.cpu_map	 = process_cpu_map_event,
 			.ordered_events	 = true,
 			.ordering_requires_timestamps = true,
+			.per_event_dump = false,
 		},
 	};
 	struct perf_data_file file = {
@@ -2799,6 +2800,8 @@ int cmd_script(int argc, const char **argv)
 		    "Show context switch events (if recorded)"),
 	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
 		    "Show namespace events (if recorded)"),
+	OPT_BOOLEAN('\0', "per-event-dump", &script.tool.per_event_dump,
+		    "print trace output to files named by the monitored events"),
 	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
 	OPT_INTEGER(0, "max-blocks", &max_blocks,
 		    "Maximum number of code blocks to dump with brstackinsn"),
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index db65878..b1fb949 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -4,6 +4,7 @@
 #include <linux/list.h>
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdio.h>
 #include <linux/perf_event.h>
 #include <linux/types.h>
 #include "xyarray.h"
@@ -128,9 +129,11 @@ struct perf_evsel {
 	unsigned long		*per_pkg_mask;
 	struct perf_evsel	*leader;
 	char			*group_name;
+	char			*filename;
 	bool			cmdline_group_boundary;
 	struct list_head	config_terms;
 	int			bpf_fd;
+	unsigned long		samples;
 	bool			auto_merge_stats;
 	bool			merged_stat;
 	const char *		metric_expr;
@@ -138,6 +141,7 @@ struct perf_evsel {
 	struct perf_evsel	**metric_events;
 	bool			collect_stat;
 	bool			weak_group;
+	FILE			*dump_event_fp;
 };
 
 union u64_swap {
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index d549e50..c7ce621 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -2,6 +2,7 @@
 #define __PERF_TOOL_H
 
 #include <stdbool.h>
+#include <stdio.h>
 
 #include <linux/types.h>
 
@@ -75,6 +76,8 @@ struct perf_tool {
 	bool		ordered_events;
 	bool		ordering_requires_timestamps;
 	bool		namespace_events;
+	bool		per_event_dump;
+	const char	*last_evsel_name;
 	enum show_feature_header show_feat_hdr;
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/4] Add fp argument to print functions
  2017-10-11 18:23 [PATCH v3 0/4] perf script: Add script per-event-dump support ufo19890607
  2017-10-11 18:23 ` [PATCH v3 1/4] Add two elements for perf_tool struct, and add three elements for perf_evsel struct, and add the per-event-dump option for perf script ufo19890607
@ 2017-10-11 18:23 ` ufo19890607
  2017-10-17 14:01   ` Arnaldo Carvalho de Melo
  2017-10-11 18:23 ` [PATCH v3 3/4] Replace printf with fprintf for all " ufo19890607
  2017-10-11 18:24 ` [PATCH v3 4/4] Make all print functions receive the fp argument, open and close the dump_event file for each evsel, and calculate the dump_event file's size ufo19890607
  3 siblings, 1 reply; 7+ messages in thread
From: ufo19890607 @ 2017-10-11 18:23 UTC (permalink / raw)
  To: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian
  Cc: linux-perf-users, linux-kernel

From: yuzhoujian <yuzhoujian@didichuxing.com>

This patch will add the fp argument to all the print functions so that they can use different
file pointer to print on the screen or dump in the file.

Changes since v2:
- none

Changes since v1:
- add the __maybe_unused attribute for the fp argument in all the print functions,
 because the fp is not used in this patch but needed in the later patches.
- split the original patch(Makes all those related functions receive the FILE
 pointer) to two simple patches, and this is the first part.

Signed-off-by: yuzhoujian <yuzhoujian@didichuxing.com>
---
 tools/perf/builtin-script.c | 190 +++++++++++++++++++++++---------------------
 1 file changed, 100 insertions(+), 90 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4ffa716..4b51dd1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -500,8 +500,8 @@ static int perf_session__check_output_opt(struct perf_session *session)
 	return 0;
 }
 
-static void print_sample_iregs(struct perf_sample *sample,
-			  struct perf_event_attr *attr)
+static void fprint_sample_iregs(struct perf_sample *sample,
+			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
 {
 	struct regs_dump *regs = &sample->intr_regs;
 	uint64_t mask = attr->sample_regs_intr;
@@ -516,8 +516,8 @@ static void print_sample_iregs(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_uregs(struct perf_sample *sample,
-			  struct perf_event_attr *attr)
+static void fprint_sample_uregs(struct perf_sample *sample,
+			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
 {
 	struct regs_dump *regs = &sample->user_regs;
 	uint64_t mask = attr->sample_regs_user;
@@ -534,9 +534,9 @@ static void print_sample_uregs(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_start(struct perf_sample *sample,
+static void fprint_sample_start(struct perf_sample *sample,
 			       struct thread *thread,
-			       struct perf_evsel *evsel)
+			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	unsigned long secs;
@@ -589,9 +589,10 @@ static void print_sample_start(struct perf_sample *sample,
 	return br->flags.predicted ? 'P' : 'M';
 }
 
-static void print_sample_brstack(struct perf_sample *sample,
+static void fprint_sample_brstack(struct perf_sample *sample,
 				 struct thread *thread,
-				 struct perf_event_attr *attr)
+				 struct perf_event_attr *attr,
+				 FILE *fp __maybe_unused)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -633,9 +634,10 @@ static void print_sample_brstack(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_brstacksym(struct perf_sample *sample,
+static void fprint_sample_brstacksym(struct perf_sample *sample,
 				    struct thread *thread,
-				    struct perf_event_attr *attr)
+				    struct perf_event_attr *attr,
+				    FILE *fp __maybe_unused)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -680,9 +682,10 @@ static void print_sample_brstacksym(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_brstackoff(struct perf_sample *sample,
+static void fprint_sample_brstackoff(struct perf_sample *sample,
 				    struct thread *thread,
-				    struct perf_event_attr *attr)
+				    struct perf_event_attr *attr,
+				    FILE *fp __maybe_unused)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -789,9 +792,9 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
 	return len;
 }
 
-static void print_jump(uint64_t ip, struct branch_entry *en,
+static void fprint_jump(uint64_t ip, struct branch_entry *en,
 		       struct perf_insn *x, u8 *inbuf, int len,
-		       int insn)
+		       int insn, FILE *fp __maybe_unused)
 {
 	printf("\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
 	       ip,
@@ -808,9 +811,10 @@ static void print_jump(uint64_t ip, struct branch_entry *en,
 	putchar('\n');
 }
 
-static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
+static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 			 uint64_t addr, struct symbol **lastsym,
-			 struct perf_event_attr *attr)
+			 struct perf_event_attr *attr,
+			 FILE *fp __maybe_unused)
 {
 	struct addr_location al;
 	int off;
@@ -846,10 +850,11 @@ static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 	*lastsym = al.sym;
 }
 
-static void print_sample_brstackinsn(struct perf_sample *sample,
+static void fprint_sample_brstackinsn(struct perf_sample *sample,
 				     struct thread *thread,
 				     struct perf_event_attr *attr,
-				     struct machine *machine)
+				     struct machine *machine,
+				     FILE *fp __maybe_unused)
 {
 	struct branch_stack *br = sample->branch_stack;
 	u64 start, end;
@@ -875,10 +880,10 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
 			br->entries[nr-1].from,
 			machine, thread, &x.is64bit, &x.cpumode, false);
 	if (len > 0) {
-		print_ip_sym(thread, x.cpumode, x.cpu,
-			     br->entries[nr - 1].from, &lastsym, attr);
-		print_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
-			    &x, buffer, len, 0);
+		fprint_ip_sym(thread, x.cpumode, x.cpu,
+			     br->entries[nr - 1].from, &lastsym, attr, stdout);
+		fprint_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
+			    &x, buffer, len, 0, stdout);
 	}
 
 	/* Print all blocks */
@@ -904,9 +909,9 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
 		for (off = 0;; off += ilen) {
 			uint64_t ip = start + off;
 
-			print_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr);
+			fprint_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr, stdout);
 			if (ip == end) {
-				print_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn);
+				fprint_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, stdout);
 				break;
 			} else {
 				printf("\t%016" PRIx64 "\t%s\n", ip,
@@ -933,7 +938,7 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
 	start = br->entries[0].to;
 	end = sample->ip;
 	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
-	print_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr);
+	fprint_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr, stdout);
 	if (len <= 0) {
 		/* Print at least last IP if basic block did not work */
 		len = grab_bb(buffer, sample->ip, sample->ip,
@@ -953,9 +958,10 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_addr(struct perf_sample *sample,
+static void fprint_sample_addr(struct perf_sample *sample,
 			  struct thread *thread,
-			  struct perf_event_attr *attr)
+			  struct perf_event_attr *attr,
+			  FILE *fp __maybe_unused)
 {
 	struct addr_location al;
 
@@ -981,10 +987,11 @@ static void print_sample_addr(struct perf_sample *sample,
 	}
 }
 
-static void print_sample_callindent(struct perf_sample *sample,
+static void fprint_sample_callindent(struct perf_sample *sample,
 				    struct perf_evsel *evsel,
 				    struct thread *thread,
-				    struct addr_location *al)
+				    struct addr_location *al,
+				    FILE *fp __maybe_unused)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	size_t depth = thread_stack__depth(thread);
@@ -1037,10 +1044,11 @@ static void print_sample_callindent(struct perf_sample *sample,
 		printf("%*s", spacing - len, "");
 }
 
-static void print_insn(struct perf_sample *sample,
+static void fprint_insn(struct perf_sample *sample,
 		       struct perf_event_attr *attr,
 		       struct thread *thread,
-		       struct machine *machine)
+		       struct machine *machine,
+		       FILE *fp __maybe_unused)
 {
 	if (PRINT_FIELD(INSNLEN))
 		printf(" ilen: %d", sample->insn_len);
@@ -1052,21 +1060,22 @@ static void print_insn(struct perf_sample *sample,
 			printf(" %02x", (unsigned char)sample->insn[i]);
 	}
 	if (PRINT_FIELD(BRSTACKINSN))
-		print_sample_brstackinsn(sample, thread, attr, machine);
+		fprint_sample_brstackinsn(sample, thread, attr, machine, stdout);
 }
 
-static void print_sample_bts(struct perf_sample *sample,
+static void fprint_sample_bts(struct perf_sample *sample,
 			     struct perf_evsel *evsel,
 			     struct thread *thread,
 			     struct addr_location *al,
-			     struct machine *machine)
+			     struct machine *machine,
+			     FILE *fp __maybe_unused)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	unsigned int type = output_type(attr->type);
 	bool print_srcline_last = false;
 
 	if (PRINT_FIELD(CALLINDENT))
-		print_sample_callindent(sample, evsel, thread, al);
+		fprint_sample_callindent(sample, evsel, thread, al, stdout);
 
 	/* print branch_from information */
 	if (PRINT_FIELD(IP)) {
@@ -1095,13 +1104,13 @@ static void print_sample_bts(struct perf_sample *sample,
 	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
 	     !output[type].user_set)) {
 		printf(" => ");
-		print_sample_addr(sample, thread, attr);
+		fprint_sample_addr(sample, thread, attr, stdout);
 	}
 
 	if (print_srcline_last)
 		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
 
-	print_insn(sample, attr, thread, machine);
+	fprint_insn(sample, attr, thread, machine, stdout);
 
 	printf("\n");
 }
@@ -1126,7 +1135,7 @@ static void print_sample_bts(struct perf_sample *sample,
 	{0, NULL}
 };
 
-static void print_sample_flags(u32 flags)
+static void fprint_sample_flags(u32 flags, FILE *fp __maybe_unused)
 {
 	const char *chars = PERF_IP_FLAG_CHARS;
 	const int n = strlen(PERF_IP_FLAG_CHARS);
@@ -1162,10 +1171,11 @@ struct printer_data {
 	int line_no;
 	bool hit_nul;
 	bool is_printable;
+	FILE *fp;
 };
 
 static void
-print_sample_bpf_output_printer(enum binary_printer_ops op,
+fprint_sample_bpf_output_printer(enum binary_printer_ops op,
 				unsigned int val,
 				void *extra)
 {
@@ -1223,31 +1233,31 @@ struct printer_data {
 	}
 }
 
-static void print_sample_bpf_output(struct perf_sample *sample)
+static void fprint_sample_bpf_output(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	unsigned int nr_bytes = sample->raw_size;
-	struct printer_data printer_data = {0, false, true};
+	struct printer_data printer_data = {0, false, true, stdout};
 
 	print_binary(sample->raw_data, nr_bytes, 8,
-		     print_sample_bpf_output_printer, &printer_data);
+		     fprint_sample_bpf_output_printer, &printer_data);
 
 	if (printer_data.is_printable && printer_data.hit_nul)
 		printf("%17s \"%s\"\n", "BPF string:",
 		       (char *)(sample->raw_data));
 }
 
-static void print_sample_spacing(int len, int spacing)
+static void fprint_sample_spacing(int len, int spacing, FILE *fp __maybe_unused)
 {
 	if (len > 0 && len < spacing)
 		printf("%*s", spacing - len, "");
 }
 
-static void print_sample_pt_spacing(int len)
+static void fprint_sample_pt_spacing(int len, FILE *fp __maybe_unused)
 {
-	print_sample_spacing(len, 34);
+	fprint_sample_spacing(len, 34, stdout);
 }
 
-static void print_sample_synth_ptwrite(struct perf_sample *sample)
+static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1257,10 +1267,10 @@ static void print_sample_synth_ptwrite(struct perf_sample *sample)
 
 	len = printf(" IP: %u payload: %#" PRIx64 " ",
 		     data->ip, le64_to_cpu(data->payload));
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth_mwait(struct perf_sample *sample)
+static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1270,10 +1280,10 @@ static void print_sample_synth_mwait(struct perf_sample *sample)
 
 	len = printf(" hints: %#x extensions: %#x ",
 		     data->hints, data->extensions);
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth_pwre(struct perf_sample *sample)
+static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1283,10 +1293,10 @@ static void print_sample_synth_pwre(struct perf_sample *sample)
 
 	len = printf(" hw: %u cstate: %u sub-cstate: %u ",
 		     data->hw, data->cstate, data->subcstate);
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth_exstop(struct perf_sample *sample)
+static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1295,10 +1305,10 @@ static void print_sample_synth_exstop(struct perf_sample *sample)
 		return;
 
 	len = printf(" IP: %u ", data->ip);
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth_pwrx(struct perf_sample *sample)
+static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1309,10 +1319,10 @@ static void print_sample_synth_pwrx(struct perf_sample *sample)
 	len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ",
 		     data->deepest_cstate, data->last_cstate,
 		     data->wake_reason);
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth_cbr(struct perf_sample *sample)
+static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp __maybe_unused)
 {
 	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
 	unsigned int percent, freq;
@@ -1327,30 +1337,30 @@ static void print_sample_synth_cbr(struct perf_sample *sample)
 		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
 		len += printf("(%3u%%) ", percent);
 	}
-	print_sample_pt_spacing(len);
+	fprint_sample_pt_spacing(len, stdout);
 }
 
-static void print_sample_synth(struct perf_sample *sample,
-			       struct perf_evsel *evsel)
+static void fprint_sample_synth(struct perf_sample *sample,
+			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
 {
 	switch (evsel->attr.config) {
 	case PERF_SYNTH_INTEL_PTWRITE:
-		print_sample_synth_ptwrite(sample);
+		fprint_sample_synth_ptwrite(sample, stdout);
 		break;
 	case PERF_SYNTH_INTEL_MWAIT:
-		print_sample_synth_mwait(sample);
+		fprint_sample_synth_mwait(sample, stdout);
 		break;
 	case PERF_SYNTH_INTEL_PWRE:
-		print_sample_synth_pwre(sample);
+		fprint_sample_synth_pwre(sample, stdout);
 		break;
 	case PERF_SYNTH_INTEL_EXSTOP:
-		print_sample_synth_exstop(sample);
+		fprint_sample_synth_exstop(sample, stdout);
 		break;
 	case PERF_SYNTH_INTEL_PWRX:
-		print_sample_synth_pwrx(sample);
+		fprint_sample_synth_pwrx(sample, stdout);
 		break;
 	case PERF_SYNTH_INTEL_CBR:
-		print_sample_synth_cbr(sample);
+		fprint_sample_synth_cbr(sample, stdout);
 		break;
 	default:
 		break;
@@ -1386,7 +1396,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
 	return max;
 }
 
-static size_t data_src__printf(u64 data_src)
+static size_t data_src__fprintf(u64 data_src, FILE *fp __maybe_unused)
 {
 	struct mem_info mi = { .data_src.val = data_src };
 	char decode[100];
@@ -1406,7 +1416,7 @@ static size_t data_src__printf(u64 data_src)
 static void process_event(struct perf_script *script,
 			  struct perf_sample *sample, struct perf_evsel *evsel,
 			  struct addr_location *al,
-			  struct machine *machine)
+			  struct machine *machine, FILE *fp __maybe_unused)
 {
 	struct thread *thread = al->thread;
 	struct perf_event_attr *attr = &evsel->attr;
@@ -1415,7 +1425,7 @@ static void process_event(struct perf_script *script,
 	if (output[type].fields == 0)
 		return;
 
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 
 	if (PRINT_FIELD(PERIOD))
 		printf("%10" PRIu64 " ", sample->period);
@@ -1431,25 +1441,25 @@ static void process_event(struct perf_script *script,
 	}
 
 	if (print_flags)
-		print_sample_flags(sample->flags);
+		fprint_sample_flags(sample->flags, stdout);
 
 	if (is_bts_event(attr)) {
-		print_sample_bts(sample, evsel, thread, al, machine);
+		fprint_sample_bts(sample, evsel, thread, al, machine, stdout);
 		return;
 	}
 
 	if (PRINT_FIELD(TRACE))
-		event_format__print(evsel->tp_format, sample->cpu,
-				    sample->raw_data, sample->raw_size);
+		event_format__fprintf(evsel->tp_format, sample->cpu,
+				    sample->raw_data, sample->raw_size, stdout);
 
 	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
-		print_sample_synth(sample, evsel);
+		fprint_sample_synth(sample, evsel, stdout);
 
 	if (PRINT_FIELD(ADDR))
-		print_sample_addr(sample, thread, attr);
+		fprint_sample_addr(sample, thread, attr, stdout);
 
 	if (PRINT_FIELD(DATA_SRC))
-		data_src__printf(sample->data_src);
+		data_src__fprintf(sample->data_src, stdout);
 
 	if (PRINT_FIELD(WEIGHT))
 		printf("%16" PRIu64, sample->weight);
@@ -1467,21 +1477,21 @@ static void process_event(struct perf_script *script,
 	}
 
 	if (PRINT_FIELD(IREGS))
-		print_sample_iregs(sample, attr);
+		fprint_sample_iregs(sample, attr, stdout);
 
 	if (PRINT_FIELD(UREGS))
-		print_sample_uregs(sample, attr);
+		fprint_sample_uregs(sample, attr, stdout);
 
 	if (PRINT_FIELD(BRSTACK))
-		print_sample_brstack(sample, thread, attr);
+		fprint_sample_brstack(sample, thread, attr, stdout);
 	else if (PRINT_FIELD(BRSTACKSYM))
-		print_sample_brstacksym(sample, thread, attr);
+		fprint_sample_brstacksym(sample, thread, attr, stdout);
 	else if (PRINT_FIELD(BRSTACKOFF))
-		print_sample_brstackoff(sample, thread, attr);
+		fprint_sample_brstackoff(sample, thread, attr, stdout);
 
 	if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
-		print_sample_bpf_output(sample);
-	print_insn(sample, attr, thread, machine);
+		fprint_sample_bpf_output(sample, stdout);
+	fprint_insn(sample, attr, thread, machine, stdout);
 
 	if (PRINT_FIELD(PHYS_ADDR))
 		printf("%16" PRIx64, sample->phys_addr);
@@ -1594,7 +1604,7 @@ static int process_sample_event(struct perf_tool *tool,
 	if (scripting_ops)
 		scripting_ops->process_event(event, sample, evsel, &al);
 	else
-		process_event(scr, sample, evsel, &al, machine);
+		process_event(scr, sample, evsel, &al, machine, stdout);
 
 out_put:
 	addr_location__put(&al);
@@ -1659,7 +1669,7 @@ static int process_comm_event(struct perf_tool *tool,
 		sample->tid = event->comm.tid;
 		sample->pid = event->comm.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	ret = 0;
 out:
@@ -1694,7 +1704,7 @@ static int process_namespaces_event(struct perf_tool *tool,
 		sample->tid = event->namespaces.tid;
 		sample->pid = event->namespaces.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	ret = 0;
 out:
@@ -1727,7 +1737,7 @@ static int process_fork_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	thread__put(thread);
 
@@ -1756,7 +1766,7 @@ static int process_exit_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 
 	if (perf_event__process_exit(tool, event, sample, machine) < 0)
@@ -1791,7 +1801,7 @@ static int process_mmap_event(struct perf_tool *tool,
 		sample->tid = event->mmap.tid;
 		sample->pid = event->mmap.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	thread__put(thread);
 	return 0;
@@ -1822,7 +1832,7 @@ static int process_mmap2_event(struct perf_tool *tool,
 		sample->tid = event->mmap2.tid;
 		sample->pid = event->mmap2.pid;
 	}
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	thread__put(thread);
 	return 0;
@@ -1848,7 +1858,7 @@ static int process_switch_event(struct perf_tool *tool,
 		return -1;
 	}
 
-	print_sample_start(sample, thread, evsel);
+	fprint_sample_start(sample, thread, evsel, stdout);
 	perf_event__fprintf(event, stdout);
 	thread__put(thread);
 	return 0;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/4] Replace printf with fprintf for all print functions
  2017-10-11 18:23 [PATCH v3 0/4] perf script: Add script per-event-dump support ufo19890607
  2017-10-11 18:23 ` [PATCH v3 1/4] Add two elements for perf_tool struct, and add three elements for perf_evsel struct, and add the per-event-dump option for perf script ufo19890607
  2017-10-11 18:23 ` [PATCH v3 2/4] Add fp argument to print functions ufo19890607
@ 2017-10-11 18:23 ` ufo19890607
  2017-10-11 18:24 ` [PATCH v3 4/4] Make all print functions receive the fp argument, open and close the dump_event file for each evsel, and calculate the dump_event file's size ufo19890607
  3 siblings, 0 replies; 7+ messages in thread
From: ufo19890607 @ 2017-10-11 18:23 UTC (permalink / raw)
  To: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian
  Cc: linux-perf-users, linux-kernel

From: yuzhoujian <yuzhoujian@didichuxing.com>

This patch will replace printf with fprintf for all print functions in the
builtin-script in order to support the per-event-dump option.

Changes since v2:
- none

Changes since v1:
- remove the fp_selection_helper function for setting the fp argument, and use
 a local variable to do the same thing.

Signed-off-by: yuzhoujian <yuzhoujian@didichuxing.com>
---
 tools/perf/builtin-script.c | 178 ++++++++++++++++++++++----------------------
 1 file changed, 89 insertions(+), 89 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4b51dd1..8c297f0 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -512,7 +512,7 @@ static void fprint_sample_iregs(struct perf_sample *sample,
 
 	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);
+		fprintf(stdout, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
 	}
 }
 
@@ -526,11 +526,11 @@ static void fprint_sample_uregs(struct perf_sample *sample,
 	if (!regs || !regs->regs)
 		return;
 
-	printf(" ABI:%" PRIu64 " ", regs->abi);
+	fprintf(stdout, " ABI:%" PRIu64 " ", regs->abi);
 
 	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);
+		fprintf(stdout, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
 	}
 }
 
@@ -544,25 +544,25 @@ static void fprint_sample_start(struct perf_sample *sample,
 
 	if (PRINT_FIELD(COMM)) {
 		if (latency_format)
-			printf("%8.8s ", thread__comm_str(thread));
+			fprintf(stdout, "%8.8s ", thread__comm_str(thread));
 		else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
-			printf("%s ", thread__comm_str(thread));
+			fprintf(stdout, "%s ", thread__comm_str(thread));
 		else
-			printf("%16s ", thread__comm_str(thread));
+			fprintf(stdout, "%16s ", thread__comm_str(thread));
 	}
 
 	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
-		printf("%5d/%-5d ", sample->pid, sample->tid);
+		fprintf(stdout, "%5d/%-5d ", sample->pid, sample->tid);
 	else if (PRINT_FIELD(PID))
-		printf("%5d ", sample->pid);
+		fprintf(stdout, "%5d ", sample->pid);
 	else if (PRINT_FIELD(TID))
-		printf("%5d ", sample->tid);
+		fprintf(stdout, "%5d ", sample->tid);
 
 	if (PRINT_FIELD(CPU)) {
 		if (latency_format)
-			printf("%3d ", sample->cpu);
+			fprintf(stdout, "%3d ", sample->cpu);
 		else
-			printf("[%03d] ", sample->cpu);
+			fprintf(stdout, "[%03d] ", sample->cpu);
 	}
 
 	if (PRINT_FIELD(TIME)) {
@@ -571,11 +571,11 @@ static void fprint_sample_start(struct perf_sample *sample,
 		nsecs -= secs * NSEC_PER_SEC;
 
 		if (nanosecs)
-			printf("%5lu.%09llu: ", secs, nsecs);
+			fprintf(stdout, "%5lu.%09llu: ", secs, nsecs);
 		else {
 			char sample_time[32];
 			timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
-			printf("%12s: ", sample_time);
+			fprintf(stdout, "%12s: ", sample_time);
 		}
 	}
 }
@@ -612,21 +612,21 @@ static void fprint_sample_brstack(struct perf_sample *sample,
 			thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
 		}
 
-		printf(" 0x%"PRIx64, from);
+		fprintf(stdout, " 0x%"PRIx64, from);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alf.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
 
-		printf("/0x%"PRIx64, to);
+		fprintf(stdout, "/0x%"PRIx64, to);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alt.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
 
-		printf("/%c/%c/%c/%d ",
+		fprintf(stdout, "/%c/%c/%c/%d ",
 			mispred_str( br->entries + i),
 			br->entries[i].flags.in_tx? 'X' : '-',
 			br->entries[i].flags.abort? 'A' : '-',
@@ -663,18 +663,18 @@ static void fprint_sample_brstacksym(struct perf_sample *sample,
 
 		symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alf.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
-		putchar('/');
+		fputc('/', stdout);
 		symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alt.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
-		printf("/%c/%c/%c/%d ",
+		fprintf(stdout, "/%c/%c/%c/%d ",
 			mispred_str( br->entries + i),
 			br->entries[i].flags.in_tx? 'X' : '-',
 			br->entries[i].flags.abort? 'A' : '-',
@@ -709,19 +709,19 @@ static void fprint_sample_brstackoff(struct perf_sample *sample,
 		if (alt.map && !alt.map->dso->adjust_symbols)
 			to = map__map_ip(alt.map, to);
 
-		printf(" 0x%"PRIx64, from);
+		fprintf(stdout, " 0x%"PRIx64, from);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alf.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
-		printf("/0x%"PRIx64, to);
+		fprintf(stdout, "/0x%"PRIx64, to);
 		if (PRINT_FIELD(DSO)) {
-			printf("(");
+			fprintf(stdout, "(");
 			map__fprintf_dsoname(alt.map, stdout);
-			printf(")");
+			fprintf(stdout, ")");
 		}
-		printf("/%c/%c/%c/%d ",
+		fprintf(stdout, "/%c/%c/%c/%d ",
 			mispred_str(br->entries + i),
 			br->entries[i].flags.in_tx ? 'X' : '-',
 			br->entries[i].flags.abort ? 'A' : '-',
@@ -796,7 +796,7 @@ static void fprint_jump(uint64_t ip, struct branch_entry *en,
 		       struct perf_insn *x, u8 *inbuf, int len,
 		       int insn, FILE *fp __maybe_unused)
 {
-	printf("\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
+	fprintf(stdout, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
 	       ip,
 	       dump_insn(x, ip, inbuf, len, NULL),
 	       en->flags.predicted ? " PRED" : "",
@@ -804,11 +804,11 @@ static void fprint_jump(uint64_t ip, struct branch_entry *en,
 	       en->flags.in_tx ? " INTX" : "",
 	       en->flags.abort ? " ABORT" : "");
 	if (en->flags.cycles) {
-		printf(" %d cycles", en->flags.cycles);
+		fprintf(stdout, " %d cycles", en->flags.cycles);
 		if (insn)
-			printf(" %.2f IPC", (float)insn / en->flags.cycles);
+			fprintf(stdout, " %.2f IPC", (float)insn / en->flags.cycles);
 	}
-	putchar('\n');
+	fputc('\n', stdout);
 }
 
 static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
@@ -840,13 +840,13 @@ static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 		off = al.addr - al.sym->start;
 	else
 		off = al.addr - al.map->start - al.sym->start;
-	printf("\t%s", al.sym->name);
+	fprintf(stdout, "\t%s", al.sym->name);
 	if (off)
-		printf("%+d", off);
-	putchar(':');
+		fprintf(stdout, "%+d", off);
+	fputc(':', stdout);
 	if (PRINT_FIELD(SRCLINE))
 		map__fprintf_srcline(al.map, al.addr, "\t", stdout);
-	putchar('\n');
+	fputc('\n', stdout);
 	*lastsym = al.sym;
 }
 
@@ -873,7 +873,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 	x.thread = thread;
 	x.cpu = sample->cpu;
 
-	putchar('\n');
+	fputc('\n', stdout);
 
 	/* Handle first from jump, of which we don't know the entry. */
 	len = grab_bb(buffer, br->entries[nr-1].from,
@@ -889,7 +889,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 	/* Print all blocks */
 	for (i = nr - 2; i >= 0; i--) {
 		if (br->entries[i].from || br->entries[i].to)
-			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
+			fprintf(stdout, "%d: %" PRIx64 "-%" PRIx64 "\n", i,
 				 br->entries[i].from,
 				 br->entries[i].to);
 		start = br->entries[i + 1].to;
@@ -899,7 +899,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 		/* Patch up missing kernel transfers due to ring filters */
 		if (len == -ENXIO && i > 0) {
 			end = br->entries[--i].from;
-			pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
+			fprintf(stdout, "\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
 			len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
 		}
 		if (len <= 0)
@@ -914,7 +914,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 				fprint_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, stdout);
 				break;
 			} else {
-				printf("\t%016" PRIx64 "\t%s\n", ip,
+				fprintf(stdout, "\t%016" PRIx64 "\t%s\n", ip,
 					dump_insn(&x, ip, buffer + off, len - off, &ilen));
 				if (ilen == 0)
 					break;
@@ -946,12 +946,12 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 		if (len <= 0)
 			return;
 
-		printf("\t%016" PRIx64 "\t%s\n", sample->ip,
+		fprintf(stdout, "\t%016" PRIx64 "\t%s\n", sample->ip,
 			dump_insn(&x, sample->ip, buffer, len, NULL));
 		return;
 	}
 	for (off = 0; off <= end - start; off += ilen) {
-		printf("\t%016" PRIx64 "\t%s\n", start + off,
+		fprintf(stdout, "\t%016" PRIx64 "\t%s\n", start + off,
 			dump_insn(&x, start + off, buffer + off, len - off, &ilen));
 		if (ilen == 0)
 			break;
@@ -965,7 +965,7 @@ static void fprint_sample_addr(struct perf_sample *sample,
 {
 	struct addr_location al;
 
-	printf("%16" PRIx64, sample->addr);
+	fprintf(stdout, "%16" PRIx64, sample->addr);
 
 	if (!sample_addr_correlates_sym(attr))
 		return;
@@ -973,7 +973,7 @@ static void fprint_sample_addr(struct perf_sample *sample,
 	thread__resolve(thread, &al, sample);
 
 	if (PRINT_FIELD(SYM)) {
-		printf(" ");
+		fprintf(stdout, " ");
 		if (PRINT_FIELD(SYMOFFSET))
 			symbol__fprintf_symname_offs(al.sym, &al, stdout);
 		else
@@ -981,9 +981,9 @@ static void fprint_sample_addr(struct perf_sample *sample,
 	}
 
 	if (PRINT_FIELD(DSO)) {
-		printf(" (");
+		fprintf(stdout, " (");
 		map__fprintf_dsoname(al.map, stdout);
-		printf(")");
+		fprintf(stdout, ")");
 	}
 }
 
@@ -1026,9 +1026,9 @@ static void fprint_sample_callindent(struct perf_sample *sample,
 	}
 
 	if (name)
-		len = printf("%*s%s", (int)depth * 4, "", name);
+		len = fprintf(stdout, "%*s%s", (int)depth * 4, "", name);
 	else if (ip)
-		len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip);
+		len = fprintf(stdout, "%*s%16" PRIx64, (int)depth * 4, "", ip);
 
 	if (len < 0)
 		return;
@@ -1041,7 +1041,7 @@ static void fprint_sample_callindent(struct perf_sample *sample,
 		spacing = round_up(len + 4, 32);
 
 	if (len < spacing)
-		printf("%*s", spacing - len, "");
+		fprintf(stdout, "%*s", spacing - len, "");
 }
 
 static void fprint_insn(struct perf_sample *sample,
@@ -1051,13 +1051,13 @@ static void fprint_insn(struct perf_sample *sample,
 		       FILE *fp __maybe_unused)
 {
 	if (PRINT_FIELD(INSNLEN))
-		printf(" ilen: %d", sample->insn_len);
+		fprintf(stdout, " ilen: %d", sample->insn_len);
 	if (PRINT_FIELD(INSN)) {
 		int i;
 
-		printf(" insn:");
+		fprintf(stdout, " insn:");
 		for (i = 0; i < sample->insn_len; i++)
-			printf(" %02x", (unsigned char)sample->insn[i]);
+			fprintf(stdout, " %02x", (unsigned char)sample->insn[i]);
 	}
 	if (PRINT_FIELD(BRSTACKINSN))
 		fprint_sample_brstackinsn(sample, thread, attr, machine, stdout);
@@ -1088,13 +1088,13 @@ static void fprint_sample_bts(struct perf_sample *sample,
 			cursor = &callchain_cursor;
 
 		if (cursor == NULL) {
-			putchar(' ');
+			fputc(' ', stdout);
 			if (print_opts & EVSEL__PRINT_SRCLINE) {
 				print_srcline_last = true;
 				print_opts &= ~EVSEL__PRINT_SRCLINE;
 			}
 		} else
-			putchar('\n');
+			fputc('\n', stdout);
 
 		sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout);
 	}
@@ -1103,7 +1103,7 @@ static void fprint_sample_bts(struct perf_sample *sample,
 	if (PRINT_FIELD(ADDR) ||
 	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
 	     !output[type].user_set)) {
-		printf(" => ");
+		fprintf(stdout, " => ");
 		fprint_sample_addr(sample, thread, attr, stdout);
 	}
 
@@ -1112,7 +1112,7 @@ static void fprint_sample_bts(struct perf_sample *sample,
 
 	fprint_insn(sample, attr, thread, machine, stdout);
 
-	printf("\n");
+	fprintf(stdout, "\n");
 }
 
 static struct {
@@ -1162,9 +1162,9 @@ static void fprint_sample_flags(u32 flags, FILE *fp __maybe_unused)
 	str[pos] = 0;
 
 	if (name)
-		printf("  %-7s%4s ", name, in_tx ? "(x)" : "");
+		fprintf(stdout, "  %-7s%4s ", name, in_tx ? "(x)" : "");
 	else
-		printf("  %-11s ", str);
+		fprintf(stdout, "  %-11s ", str);
 }
 
 struct printer_data {
@@ -1184,30 +1184,30 @@ struct printer_data {
 
 	switch (op) {
 	case BINARY_PRINT_DATA_BEGIN:
-		printf("\n");
+		fprintf(stdout, "\n");
 		break;
 	case BINARY_PRINT_LINE_BEGIN:
-		printf("%17s", !printer_data->line_no ? "BPF output:" :
+		fprintf(stdout, "%17s", !printer_data->line_no ? "BPF output:" :
 						        "           ");
 		break;
 	case BINARY_PRINT_ADDR:
-		printf(" %04x:", val);
+		fprintf(stdout, " %04x:", val);
 		break;
 	case BINARY_PRINT_NUM_DATA:
-		printf(" %02x", val);
+		fprintf(stdout, " %02x", val);
 		break;
 	case BINARY_PRINT_NUM_PAD:
-		printf("   ");
+		fprintf(stdout, "   ");
 		break;
 	case BINARY_PRINT_SEP:
-		printf("  ");
+		fprintf(stdout, "  ");
 		break;
 	case BINARY_PRINT_CHAR_DATA:
 		if (printer_data->hit_nul && ch)
 			printer_data->is_printable = false;
 
 		if (!isprint(ch)) {
-			printf("%c", '.');
+			fprintf(stdout, "%c", '.');
 
 			if (!printer_data->is_printable)
 				break;
@@ -1217,14 +1217,14 @@ struct printer_data {
 			else
 				printer_data->is_printable = false;
 		} else {
-			printf("%c", ch);
+			fprintf(stdout, "%c", ch);
 		}
 		break;
 	case BINARY_PRINT_CHAR_PAD:
-		printf(" ");
+		fprintf(stdout, " ");
 		break;
 	case BINARY_PRINT_LINE_END:
-		printf("\n");
+		fprintf(stdout, "\n");
 		printer_data->line_no++;
 		break;
 	case BINARY_PRINT_DATA_END:
@@ -1242,14 +1242,14 @@ static void fprint_sample_bpf_output(struct perf_sample *sample, FILE *fp __mayb
 		     fprint_sample_bpf_output_printer, &printer_data);
 
 	if (printer_data.is_printable && printer_data.hit_nul)
-		printf("%17s \"%s\"\n", "BPF string:",
+		fprintf(stdout, "%17s \"%s\"\n", "BPF string:",
 		       (char *)(sample->raw_data));
 }
 
 static void fprint_sample_spacing(int len, int spacing, FILE *fp __maybe_unused)
 {
 	if (len > 0 && len < spacing)
-		printf("%*s", spacing - len, "");
+		fprintf(stdout, "%*s", spacing - len, "");
 }
 
 static void fprint_sample_pt_spacing(int len, FILE *fp __maybe_unused)
@@ -1265,7 +1265,7 @@ static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp __m
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = printf(" IP: %u payload: %#" PRIx64 " ",
+	len = fprintf(stdout, " IP: %u payload: %#" PRIx64 " ",
 		     data->ip, le64_to_cpu(data->payload));
 	fprint_sample_pt_spacing(len, stdout);
 }
@@ -1278,7 +1278,7 @@ static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp __may
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = printf(" hints: %#x extensions: %#x ",
+	len = fprintf(stdout, " hints: %#x extensions: %#x ",
 		     data->hints, data->extensions);
 	fprint_sample_pt_spacing(len, stdout);
 }
@@ -1291,7 +1291,7 @@ static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp __mayb
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = printf(" hw: %u cstate: %u sub-cstate: %u ",
+	len = fprintf(stdout, " hw: %u cstate: %u sub-cstate: %u ",
 		     data->hw, data->cstate, data->subcstate);
 	fprint_sample_pt_spacing(len, stdout);
 }
@@ -1304,7 +1304,7 @@ static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp __ma
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = printf(" IP: %u ", data->ip);
+	len = fprintf(stdout, " IP: %u ", data->ip);
 	fprint_sample_pt_spacing(len, stdout);
 }
 
@@ -1316,7 +1316,7 @@ static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp __mayb
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ",
+	len = fprintf(stdout, " deepest cstate: %u last cstate: %u wake reason: %#x ",
 		     data->deepest_cstate, data->last_cstate,
 		     data->wake_reason);
 	fprint_sample_pt_spacing(len, stdout);
@@ -1332,10 +1332,10 @@ static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp __maybe
 		return;
 
 	freq = (le32_to_cpu(data->freq) + 500) / 1000;
-	len = printf(" cbr: %2u freq: %4u MHz ", data->cbr, freq);
+	len = fprintf(stdout, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
 	if (data->max_nonturbo) {
 		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
-		len += printf("(%3u%%) ", percent);
+		len += fprintf(stdout, "(%3u%%) ", percent);
 	}
 	fprint_sample_pt_spacing(len, stdout);
 }
@@ -1410,7 +1410,7 @@ static size_t data_src__fprintf(u64 data_src, FILE *fp __maybe_unused)
 	if (maxlen < len)
 		maxlen = len;
 
-	return printf("%-*s", maxlen, out);
+	return fprintf(stdout, "%-*s", maxlen, out);
 }
 
 static void process_event(struct perf_script *script,
@@ -1428,7 +1428,7 @@ static void process_event(struct perf_script *script,
 	fprint_sample_start(sample, thread, evsel, stdout);
 
 	if (PRINT_FIELD(PERIOD))
-		printf("%10" PRIu64 " ", sample->period);
+		fprintf(stdout, "%10" PRIu64 " ", sample->period);
 
 	if (PRINT_FIELD(EVNAME)) {
 		const char *evname = perf_evsel__name(evsel);
@@ -1436,7 +1436,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(stdout, "%*s: ", script->name_width,
 		       evname ? evname : "[unknown]");
 	}
 
@@ -1462,7 +1462,7 @@ static void process_event(struct perf_script *script,
 		data_src__fprintf(sample->data_src, stdout);
 
 	if (PRINT_FIELD(WEIGHT))
-		printf("%16" PRIu64, sample->weight);
+		fprintf(stdout, "%16" PRIu64, sample->weight);
 
 	if (PRINT_FIELD(IP)) {
 		struct callchain_cursor *cursor = NULL;
@@ -1472,7 +1472,7 @@ static void process_event(struct perf_script *script,
 					      sample, NULL, NULL, scripting_max_stack) == 0)
 			cursor = &callchain_cursor;
 
-		putchar(cursor ? '\n' : ' ');
+		fputc(cursor ? '\n' : ' ', stdout);
 		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, stdout);
 	}
 
@@ -1494,8 +1494,8 @@ static void process_event(struct perf_script *script,
 	fprint_insn(sample, attr, thread, machine, stdout);
 
 	if (PRINT_FIELD(PHYS_ADDR))
-		printf("%16" PRIx64, sample->phys_addr);
-	printf("\n");
+		fprintf(stdout, "%16" PRIx64, sample->phys_addr);
+	fprintf(stdout, "\n");
 }
 
 static struct scripting_ops	*scripting_ops;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 4/4] Make all print functions receive the fp argument, open and close the dump_event file for each evsel, and calculate the dump_event file's size.
  2017-10-11 18:23 [PATCH v3 0/4] perf script: Add script per-event-dump support ufo19890607
                   ` (2 preceding siblings ...)
  2017-10-11 18:23 ` [PATCH v3 3/4] Replace printf with fprintf for all " ufo19890607
@ 2017-10-11 18:24 ` ufo19890607
  3 siblings, 0 replies; 7+ messages in thread
From: ufo19890607 @ 2017-10-11 18:24 UTC (permalink / raw)
  To: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian
  Cc: linux-perf-users, linux-kernel

From: yuzhoujian <yuzhoujian@didichuxing.com>

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
calculate its size.

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@didichuxing.com>
---
 tools/perf/builtin-script.c | 416 ++++++++++++++++++++++++--------------------
 tools/perf/util/session.c   |  16 +-
 2 files changed, 247 insertions(+), 185 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 8c297f0..db6a5bb 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -501,7 +501,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
 }
 
 static void fprint_sample_iregs(struct perf_sample *sample,
-			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
+			  struct perf_event_attr *attr, FILE *fp)
 {
 	struct regs_dump *regs = &sample->intr_regs;
 	uint64_t mask = attr->sample_regs_intr;
@@ -512,12 +512,12 @@ static void fprint_sample_iregs(struct perf_sample *sample,
 
 	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
 		u64 val = regs->regs[i++];
-		fprintf(stdout, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
+		fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
 	}
 }
 
 static void fprint_sample_uregs(struct perf_sample *sample,
-			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
+			  struct perf_event_attr *attr, FILE *fp)
 {
 	struct regs_dump *regs = &sample->user_regs;
 	uint64_t mask = attr->sample_regs_user;
@@ -526,17 +526,17 @@ static void fprint_sample_uregs(struct perf_sample *sample,
 	if (!regs || !regs->regs)
 		return;
 
-	fprintf(stdout, " ABI:%" PRIu64 " ", regs->abi);
+	fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
 
 	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
 		u64 val = regs->regs[i++];
-		fprintf(stdout, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
+		fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
 	}
 }
 
 static void fprint_sample_start(struct perf_sample *sample,
 			       struct thread *thread,
-			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
+			       struct perf_evsel *evsel, FILE *fp)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	unsigned long secs;
@@ -544,25 +544,25 @@ static void fprint_sample_start(struct perf_sample *sample,
 
 	if (PRINT_FIELD(COMM)) {
 		if (latency_format)
-			fprintf(stdout, "%8.8s ", thread__comm_str(thread));
+			fprintf(fp, "%8.8s ", thread__comm_str(thread));
 		else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
-			fprintf(stdout, "%s ", thread__comm_str(thread));
+			fprintf(fp, "%s ", thread__comm_str(thread));
 		else
-			fprintf(stdout, "%16s ", thread__comm_str(thread));
+			fprintf(fp, "%16s ", thread__comm_str(thread));
 	}
 
 	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
-		fprintf(stdout, "%5d/%-5d ", sample->pid, sample->tid);
+		fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
 	else if (PRINT_FIELD(PID))
-		fprintf(stdout, "%5d ", sample->pid);
+		fprintf(fp, "%5d ", sample->pid);
 	else if (PRINT_FIELD(TID))
-		fprintf(stdout, "%5d ", sample->tid);
+		fprintf(fp, "%5d ", sample->tid);
 
 	if (PRINT_FIELD(CPU)) {
 		if (latency_format)
-			fprintf(stdout, "%3d ", sample->cpu);
+			fprintf(fp, "%3d ", sample->cpu);
 		else
-			fprintf(stdout, "[%03d] ", sample->cpu);
+			fprintf(fp, "[%03d] ", sample->cpu);
 	}
 
 	if (PRINT_FIELD(TIME)) {
@@ -571,11 +571,11 @@ static void fprint_sample_start(struct perf_sample *sample,
 		nsecs -= secs * NSEC_PER_SEC;
 
 		if (nanosecs)
-			fprintf(stdout, "%5lu.%09llu: ", secs, nsecs);
+			fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
 		else {
 			char sample_time[32];
 			timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
-			fprintf(stdout, "%12s: ", sample_time);
+			fprintf(fp, "%12s: ", sample_time);
 		}
 	}
 }
@@ -592,7 +592,7 @@ static void fprint_sample_start(struct perf_sample *sample,
 static void fprint_sample_brstack(struct perf_sample *sample,
 				 struct thread *thread,
 				 struct perf_event_attr *attr,
-				 FILE *fp __maybe_unused)
+				 FILE *fp)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -612,21 +612,21 @@ static void fprint_sample_brstack(struct perf_sample *sample,
 			thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
 		}
 
-		fprintf(stdout, " 0x%"PRIx64, from);
+		fprintf(fp, "0x%"PRIx64, from);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alf.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alf.map, fp);
+			fprintf(fp, ")");
 		}
 
-		fprintf(stdout, "/0x%"PRIx64, to);
+		fprintf(fp, "/0x%"PRIx64, to);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alt.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alt.map, fp);
+			fprintf(fp, ")");
 		}
 
-		fprintf(stdout, "/%c/%c/%c/%d ",
+		fprintf(fp, "/%c/%c/%c/%d ",
 			mispred_str( br->entries + i),
 			br->entries[i].flags.in_tx? 'X' : '-',
 			br->entries[i].flags.abort? 'A' : '-',
@@ -637,7 +637,7 @@ static void fprint_sample_brstack(struct perf_sample *sample,
 static void fprint_sample_brstacksym(struct perf_sample *sample,
 				    struct thread *thread,
 				    struct perf_event_attr *attr,
-				    FILE *fp __maybe_unused)
+				    FILE *fp)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -661,20 +661,20 @@ static void fprint_sample_brstacksym(struct perf_sample *sample,
 		if (alt.map)
 			alt.sym = map__find_symbol(alt.map, alt.addr);
 
-		symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
+		symbol__fprintf_symname_offs(alf.sym, &alf, fp);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alf.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alf.map, fp);
+			fprintf(fp, ")");
 		}
-		fputc('/', stdout);
-		symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
+		fputc('/', fp);
+		symbol__fprintf_symname_offs(alt.sym, &alt, fp);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alt.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alt.map, fp);
+			fprintf(fp, ")");
 		}
-		fprintf(stdout, "/%c/%c/%c/%d ",
+		fprintf(fp, "/%c/%c/%c/%d ",
 			mispred_str( br->entries + i),
 			br->entries[i].flags.in_tx? 'X' : '-',
 			br->entries[i].flags.abort? 'A' : '-',
@@ -685,7 +685,7 @@ static void fprint_sample_brstacksym(struct perf_sample *sample,
 static void fprint_sample_brstackoff(struct perf_sample *sample,
 				    struct thread *thread,
 				    struct perf_event_attr *attr,
-				    FILE *fp __maybe_unused)
+				    FILE *fp)
 {
 	struct branch_stack *br = sample->branch_stack;
 	struct addr_location alf, alt;
@@ -709,19 +709,19 @@ static void fprint_sample_brstackoff(struct perf_sample *sample,
 		if (alt.map && !alt.map->dso->adjust_symbols)
 			to = map__map_ip(alt.map, to);
 
-		fprintf(stdout, " 0x%"PRIx64, from);
+		fprintf(fp, "0x%"PRIx64, from);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alf.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alf.map, fp);
+			fprintf(fp, ")");
 		}
-		fprintf(stdout, "/0x%"PRIx64, to);
+		fprintf(fp, "/0x%"PRIx64, to);
 		if (PRINT_FIELD(DSO)) {
-			fprintf(stdout, "(");
-			map__fprintf_dsoname(alt.map, stdout);
-			fprintf(stdout, ")");
+			fprintf(fp, "(");
+			map__fprintf_dsoname(alt.map, fp);
+			fprintf(fp, ")");
 		}
-		fprintf(stdout, "/%c/%c/%c/%d ",
+		fprintf(fp, "/%c/%c/%c/%d ",
 			mispred_str(br->entries + i),
 			br->entries[i].flags.in_tx ? 'X' : '-',
 			br->entries[i].flags.abort ? 'A' : '-',
@@ -794,9 +794,9 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
 
 static void fprint_jump(uint64_t ip, struct branch_entry *en,
 		       struct perf_insn *x, u8 *inbuf, int len,
-		       int insn, FILE *fp __maybe_unused)
+		       int insn, FILE *fp)
 {
-	fprintf(stdout, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
+	fprintf(fp, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
 	       ip,
 	       dump_insn(x, ip, inbuf, len, NULL),
 	       en->flags.predicted ? " PRED" : "",
@@ -804,17 +804,17 @@ static void fprint_jump(uint64_t ip, struct branch_entry *en,
 	       en->flags.in_tx ? " INTX" : "",
 	       en->flags.abort ? " ABORT" : "");
 	if (en->flags.cycles) {
-		fprintf(stdout, " %d cycles", en->flags.cycles);
+		fprintf(fp, " %d cycles", en->flags.cycles);
 		if (insn)
-			fprintf(stdout, " %.2f IPC", (float)insn / en->flags.cycles);
+			fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
 	}
-	fputc('\n', stdout);
+	fputc('\n', fp);
 }
 
 static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 			 uint64_t addr, struct symbol **lastsym,
 			 struct perf_event_attr *attr,
-			 FILE *fp __maybe_unused)
+			 FILE *fp)
 {
 	struct addr_location al;
 	int off;
@@ -840,13 +840,13 @@ static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 		off = al.addr - al.sym->start;
 	else
 		off = al.addr - al.map->start - al.sym->start;
-	fprintf(stdout, "\t%s", al.sym->name);
+	fprintf(fp, "\t%s", al.sym->name);
 	if (off)
-		fprintf(stdout, "%+d", off);
-	fputc(':', stdout);
+		fprintf(fp, "%+d", off);
+	fputc(':', fp);
 	if (PRINT_FIELD(SRCLINE))
-		map__fprintf_srcline(al.map, al.addr, "\t", stdout);
-	fputc('\n', stdout);
+		map__fprintf_srcline(al.map, al.addr, "\t", fp);
+	fputc('\n', fp);
 	*lastsym = al.sym;
 }
 
@@ -854,7 +854,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 				     struct thread *thread,
 				     struct perf_event_attr *attr,
 				     struct machine *machine,
-				     FILE *fp __maybe_unused)
+				     FILE *fp)
 {
 	struct branch_stack *br = sample->branch_stack;
 	u64 start, end;
@@ -873,7 +873,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 	x.thread = thread;
 	x.cpu = sample->cpu;
 
-	fputc('\n', stdout);
+	fputc('\n', fp);
 
 	/* Handle first from jump, of which we don't know the entry. */
 	len = grab_bb(buffer, br->entries[nr-1].from,
@@ -881,15 +881,15 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 			machine, thread, &x.is64bit, &x.cpumode, false);
 	if (len > 0) {
 		fprint_ip_sym(thread, x.cpumode, x.cpu,
-			     br->entries[nr - 1].from, &lastsym, attr, stdout);
+			     br->entries[nr - 1].from, &lastsym, attr, fp);
 		fprint_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
-			    &x, buffer, len, 0, stdout);
+			    &x, buffer, len, 0, fp);
 	}
 
 	/* Print all blocks */
 	for (i = nr - 2; i >= 0; i--) {
 		if (br->entries[i].from || br->entries[i].to)
-			fprintf(stdout, "%d: %" PRIx64 "-%" PRIx64 "\n", i,
+			fprintf(fp, "%d: %" PRIx64 "-%" PRIx64 "\n", i,
 				 br->entries[i].from,
 				 br->entries[i].to);
 		start = br->entries[i + 1].to;
@@ -899,7 +899,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 		/* Patch up missing kernel transfers due to ring filters */
 		if (len == -ENXIO && i > 0) {
 			end = br->entries[--i].from;
-			fprintf(stdout, "\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
+			fprintf(fp, "\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
 			len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
 		}
 		if (len <= 0)
@@ -909,12 +909,12 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 		for (off = 0;; off += ilen) {
 			uint64_t ip = start + off;
 
-			fprint_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr, stdout);
+			fprint_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr, fp);
 			if (ip == end) {
-				fprint_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, stdout);
+				fprint_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp);
 				break;
 			} else {
-				fprintf(stdout, "\t%016" PRIx64 "\t%s\n", ip,
+				fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
 					dump_insn(&x, ip, buffer + off, len - off, &ilen));
 				if (ilen == 0)
 					break;
@@ -938,7 +938,7 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 	start = br->entries[0].to;
 	end = sample->ip;
 	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
-	fprint_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr, stdout);
+	fprint_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr, fp);
 	if (len <= 0) {
 		/* Print at least last IP if basic block did not work */
 		len = grab_bb(buffer, sample->ip, sample->ip,
@@ -946,12 +946,12 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 		if (len <= 0)
 			return;
 
-		fprintf(stdout, "\t%016" PRIx64 "\t%s\n", sample->ip,
+		fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
 			dump_insn(&x, sample->ip, buffer, len, NULL));
 		return;
 	}
 	for (off = 0; off <= end - start; off += ilen) {
-		fprintf(stdout, "\t%016" PRIx64 "\t%s\n", start + off,
+		fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
 			dump_insn(&x, start + off, buffer + off, len - off, &ilen));
 		if (ilen == 0)
 			break;
@@ -961,11 +961,11 @@ static void fprint_sample_brstackinsn(struct perf_sample *sample,
 static void fprint_sample_addr(struct perf_sample *sample,
 			  struct thread *thread,
 			  struct perf_event_attr *attr,
-			  FILE *fp __maybe_unused)
+			  FILE *fp)
 {
 	struct addr_location al;
 
-	fprintf(stdout, "%16" PRIx64, sample->addr);
+	fprintf(fp, "%16" PRIx64, sample->addr);
 
 	if (!sample_addr_correlates_sym(attr))
 		return;
@@ -973,17 +973,17 @@ static void fprint_sample_addr(struct perf_sample *sample,
 	thread__resolve(thread, &al, sample);
 
 	if (PRINT_FIELD(SYM)) {
-		fprintf(stdout, " ");
+		fprintf(fp, " ");
 		if (PRINT_FIELD(SYMOFFSET))
-			symbol__fprintf_symname_offs(al.sym, &al, stdout);
+			symbol__fprintf_symname_offs(al.sym, &al, fp);
 		else
-			symbol__fprintf_symname(al.sym, stdout);
+			symbol__fprintf_symname(al.sym, fp);
 	}
 
 	if (PRINT_FIELD(DSO)) {
-		fprintf(stdout, " (");
-		map__fprintf_dsoname(al.map, stdout);
-		fprintf(stdout, ")");
+		fprintf(fp, " (");
+		map__fprintf_dsoname(al.map, fp);
+		fprintf(fp, ")");
 	}
 }
 
@@ -991,7 +991,7 @@ static void fprint_sample_callindent(struct perf_sample *sample,
 				    struct perf_evsel *evsel,
 				    struct thread *thread,
 				    struct addr_location *al,
-				    FILE *fp __maybe_unused)
+				    FILE *fp)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	size_t depth = thread_stack__depth(thread);
@@ -1026,9 +1026,9 @@ static void fprint_sample_callindent(struct perf_sample *sample,
 	}
 
 	if (name)
-		len = fprintf(stdout, "%*s%s", (int)depth * 4, "", name);
+		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
 	else if (ip)
-		len = fprintf(stdout, "%*s%16" PRIx64, (int)depth * 4, "", ip);
+		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
 
 	if (len < 0)
 		return;
@@ -1041,26 +1041,26 @@ static void fprint_sample_callindent(struct perf_sample *sample,
 		spacing = round_up(len + 4, 32);
 
 	if (len < spacing)
-		fprintf(stdout, "%*s", spacing - len, "");
+		fprintf(fp, "%*s", spacing - len, "");
 }
 
 static void fprint_insn(struct perf_sample *sample,
 		       struct perf_event_attr *attr,
 		       struct thread *thread,
 		       struct machine *machine,
-		       FILE *fp __maybe_unused)
+		       FILE *fp)
 {
 	if (PRINT_FIELD(INSNLEN))
-		fprintf(stdout, " ilen: %d", sample->insn_len);
+		fprintf(fp, " ilen: %d", sample->insn_len);
 	if (PRINT_FIELD(INSN)) {
 		int i;
 
-		fprintf(stdout, " insn:");
+		fprintf(fp, " insn:");
 		for (i = 0; i < sample->insn_len; i++)
-			fprintf(stdout, " %02x", (unsigned char)sample->insn[i]);
+			fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
 	}
 	if (PRINT_FIELD(BRSTACKINSN))
-		fprint_sample_brstackinsn(sample, thread, attr, machine, stdout);
+		fprint_sample_brstackinsn(sample, thread, attr, machine, fp);
 }
 
 static void fprint_sample_bts(struct perf_sample *sample,
@@ -1068,14 +1068,14 @@ static void fprint_sample_bts(struct perf_sample *sample,
 			     struct thread *thread,
 			     struct addr_location *al,
 			     struct machine *machine,
-			     FILE *fp __maybe_unused)
+			     FILE *fp)
 {
 	struct perf_event_attr *attr = &evsel->attr;
 	unsigned int type = output_type(attr->type);
 	bool print_srcline_last = false;
 
 	if (PRINT_FIELD(CALLINDENT))
-		fprint_sample_callindent(sample, evsel, thread, al, stdout);
+		fprint_sample_callindent(sample, evsel, thread, al, fp);
 
 	/* print branch_from information */
 	if (PRINT_FIELD(IP)) {
@@ -1088,31 +1088,31 @@ static void fprint_sample_bts(struct perf_sample *sample,
 			cursor = &callchain_cursor;
 
 		if (cursor == NULL) {
-			fputc(' ', stdout);
+			fputc(' ', fp);
 			if (print_opts & EVSEL__PRINT_SRCLINE) {
 				print_srcline_last = true;
 				print_opts &= ~EVSEL__PRINT_SRCLINE;
 			}
 		} else
-			fputc('\n', stdout);
+			fputc('\n', fp);
 
-		sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout);
+		sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp);
 	}
 
 	/* print branch_to information */
 	if (PRINT_FIELD(ADDR) ||
 	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
 	     !output[type].user_set)) {
-		fprintf(stdout, " => ");
-		fprint_sample_addr(sample, thread, attr, stdout);
+		fprintf(fp, " => ");
+		fprint_sample_addr(sample, thread, attr, fp);
 	}
 
 	if (print_srcline_last)
-		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
+		map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 
-	fprint_insn(sample, attr, thread, machine, stdout);
+	fprint_insn(sample, attr, thread, machine, fp);
 
-	fprintf(stdout, "\n");
+	fprintf(fp, "\n");
 }
 
 static struct {
@@ -1135,7 +1135,7 @@ static void fprint_sample_bts(struct perf_sample *sample,
 	{0, NULL}
 };
 
-static void fprint_sample_flags(u32 flags, FILE *fp __maybe_unused)
+static void fprint_sample_flags(u32 flags, FILE *fp)
 {
 	const char *chars = PERF_IP_FLAG_CHARS;
 	const int n = strlen(PERF_IP_FLAG_CHARS);
@@ -1162,9 +1162,9 @@ static void fprint_sample_flags(u32 flags, FILE *fp __maybe_unused)
 	str[pos] = 0;
 
 	if (name)
-		fprintf(stdout, "  %-7s%4s ", name, in_tx ? "(x)" : "");
+		fprintf(fp, "  %-7s%4s ", name, in_tx ? "(x)" : "");
 	else
-		fprintf(stdout, "  %-11s ", str);
+		fprintf(fp, "  %-11s ", str);
 }
 
 struct printer_data {
@@ -1181,33 +1181,34 @@ struct printer_data {
 {
 	unsigned char ch = (unsigned char)val;
 	struct printer_data *printer_data = extra;
+	FILE *fp = printer_data->fp;
 
 	switch (op) {
 	case BINARY_PRINT_DATA_BEGIN:
-		fprintf(stdout, "\n");
+		fprintf(fp, "\n");
 		break;
 	case BINARY_PRINT_LINE_BEGIN:
-		fprintf(stdout, "%17s", !printer_data->line_no ? "BPF output:" :
+		fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
 						        "           ");
 		break;
 	case BINARY_PRINT_ADDR:
-		fprintf(stdout, " %04x:", val);
+		fprintf(fp, " %04x:", val);
 		break;
 	case BINARY_PRINT_NUM_DATA:
-		fprintf(stdout, " %02x", val);
+		fprintf(fp, " %02x", val);
 		break;
 	case BINARY_PRINT_NUM_PAD:
-		fprintf(stdout, "   ");
+		fprintf(fp, "   ");
 		break;
 	case BINARY_PRINT_SEP:
-		fprintf(stdout, "  ");
+		fprintf(fp, "  ");
 		break;
 	case BINARY_PRINT_CHAR_DATA:
 		if (printer_data->hit_nul && ch)
 			printer_data->is_printable = false;
 
 		if (!isprint(ch)) {
-			fprintf(stdout, "%c", '.');
+			fprintf(fp, "%c", '.');
 
 			if (!printer_data->is_printable)
 				break;
@@ -1217,14 +1218,14 @@ struct printer_data {
 			else
 				printer_data->is_printable = false;
 		} else {
-			fprintf(stdout, "%c", ch);
+			fprintf(fp, "%c", ch);
 		}
 		break;
 	case BINARY_PRINT_CHAR_PAD:
-		fprintf(stdout, " ");
+		fprintf(fp, " ");
 		break;
 	case BINARY_PRINT_LINE_END:
-		fprintf(stdout, "\n");
+		fprintf(fp, "\n");
 		printer_data->line_no++;
 		break;
 	case BINARY_PRINT_DATA_END:
@@ -1233,31 +1234,31 @@ struct printer_data {
 	}
 }
 
-static void fprint_sample_bpf_output(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_bpf_output(struct perf_sample *sample, FILE *fp)
 {
 	unsigned int nr_bytes = sample->raw_size;
-	struct printer_data printer_data = {0, false, true, stdout};
+	struct printer_data printer_data = {0, false, true, fp};
 
 	print_binary(sample->raw_data, nr_bytes, 8,
 		     fprint_sample_bpf_output_printer, &printer_data);
 
 	if (printer_data.is_printable && printer_data.hit_nul)
-		fprintf(stdout, "%17s \"%s\"\n", "BPF string:",
+		fprintf(fp, "%17s \"%s\"\n", "BPF string:",
 		       (char *)(sample->raw_data));
 }
 
-static void fprint_sample_spacing(int len, int spacing, FILE *fp __maybe_unused)
+static void fprint_sample_spacing(int len, int spacing, FILE *fp)
 {
 	if (len > 0 && len < spacing)
-		fprintf(stdout, "%*s", spacing - len, "");
+		fprintf(fp, "%*s", spacing - len, "");
 }
 
-static void fprint_sample_pt_spacing(int len, FILE *fp __maybe_unused)
+static void fprint_sample_pt_spacing(int len, FILE *fp)
 {
-	fprint_sample_spacing(len, 34, stdout);
+	fprint_sample_spacing(len, 34, fp);
 }
 
-static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1265,12 +1266,12 @@ static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp __m
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = fprintf(stdout, " IP: %u payload: %#" PRIx64 " ",
+	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
 		     data->ip, le64_to_cpu(data->payload));
-	fprint_sample_pt_spacing(len, stdout);
+	fprint_sample_pt_spacing(len, fp);
 }
 
-static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1278,12 +1279,12 @@ static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp __may
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = fprintf(stdout, " hints: %#x extensions: %#x ",
+	len = fprintf(fp, " hints: %#x extensions: %#x ",
 		     data->hints, data->extensions);
-	fprint_sample_pt_spacing(len, stdout);
+	fprint_sample_pt_spacing(len, fp);
 }
 
-static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1291,12 +1292,12 @@ static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp __mayb
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = fprintf(stdout, " hw: %u cstate: %u sub-cstate: %u ",
+	len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
 		     data->hw, data->cstate, data->subcstate);
-	fprint_sample_pt_spacing(len, stdout);
+	fprint_sample_pt_spacing(len, fp);
 }
 
-static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1304,11 +1305,11 @@ static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp __ma
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = fprintf(stdout, " IP: %u ", data->ip);
-	fprint_sample_pt_spacing(len, stdout);
+	len = fprintf(fp, " IP: %u ", data->ip);
+	fprint_sample_pt_spacing(len, fp);
 }
 
-static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
 	int len;
@@ -1316,13 +1317,13 @@ static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp __mayb
 	if (perf_sample__bad_synth_size(sample, *data))
 		return;
 
-	len = fprintf(stdout, " deepest cstate: %u last cstate: %u wake reason: %#x ",
+	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
 		     data->deepest_cstate, data->last_cstate,
 		     data->wake_reason);
-	fprint_sample_pt_spacing(len, stdout);
+	fprint_sample_pt_spacing(len, fp);
 }
 
-static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp __maybe_unused)
+static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp)
 {
 	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
 	unsigned int percent, freq;
@@ -1332,35 +1333,35 @@ static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp __maybe
 		return;
 
 	freq = (le32_to_cpu(data->freq) + 500) / 1000;
-	len = fprintf(stdout, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
+	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
 	if (data->max_nonturbo) {
 		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
-		len += fprintf(stdout, "(%3u%%) ", percent);
+		len += fprintf(fp, "(%3u%%) ", percent);
 	}
-	fprint_sample_pt_spacing(len, stdout);
+	fprint_sample_pt_spacing(len, fp);
 }
 
 static void fprint_sample_synth(struct perf_sample *sample,
-			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
+			       struct perf_evsel *evsel, FILE *fp)
 {
 	switch (evsel->attr.config) {
 	case PERF_SYNTH_INTEL_PTWRITE:
-		fprint_sample_synth_ptwrite(sample, stdout);
+		fprint_sample_synth_ptwrite(sample, fp);
 		break;
 	case PERF_SYNTH_INTEL_MWAIT:
-		fprint_sample_synth_mwait(sample, stdout);
+		fprint_sample_synth_mwait(sample, fp);
 		break;
 	case PERF_SYNTH_INTEL_PWRE:
-		fprint_sample_synth_pwre(sample, stdout);
+		fprint_sample_synth_pwre(sample, fp);
 		break;
 	case PERF_SYNTH_INTEL_EXSTOP:
-		fprint_sample_synth_exstop(sample, stdout);
+		fprint_sample_synth_exstop(sample, fp);
 		break;
 	case PERF_SYNTH_INTEL_PWRX:
-		fprint_sample_synth_pwrx(sample, stdout);
+		fprint_sample_synth_pwrx(sample, fp);
 		break;
 	case PERF_SYNTH_INTEL_CBR:
-		fprint_sample_synth_cbr(sample, stdout);
+		fprint_sample_synth_cbr(sample, fp);
 		break;
 	default:
 		break;
@@ -1396,7 +1397,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
 	return max;
 }
 
-static size_t data_src__fprintf(u64 data_src, FILE *fp __maybe_unused)
+static size_t data_src__fprintf(u64 data_src, FILE *fp)
 {
 	struct mem_info mi = { .data_src.val = data_src };
 	char decode[100];
@@ -1410,13 +1411,45 @@ static size_t data_src__fprintf(u64 data_src, FILE *fp __maybe_unused)
 	if (maxlen < len)
 		maxlen = len;
 
-	return fprintf(stdout, "%-*s", maxlen, out);
+	return fprintf(fp, "%-*s", maxlen, out);
+}
+
+static FILE *fp_selection_helper(struct perf_script *script, struct perf_evsel *evsel)
+{
+	const char *evname;
+	const char *file_name;
+	char *filename;
+	FILE *fp;
+	struct perf_tool *tool;
+
+	tool = &script->tool;
+	evname = perf_evsel__name(evsel);
+	file_name = script->session->file->path;
+	if (tool->per_event_dump) {
+		/* if evname and last evsel name is not the same, opens a new dump file. */
+		if (evname != tool->last_evsel_name) {
+			if (asprintf(&filename, "%s%s%s%s", file_name, "-script-dump-",
+					evname, ".txt") < 0)
+				return NULL;
+			fp = fopen(filename, "a+");
+			if (!fp)
+				return NULL;
+			evsel->filename = filename;
+			tool->last_evsel_name = evname;
+			evsel->dump_event_fp = fp;
+		} else {
+			fp = evsel->dump_event_fp;
+		}
+	} 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,
-			  struct machine *machine, FILE *fp __maybe_unused)
+			  struct machine *machine, FILE *fp)
 {
 	struct thread *thread = al->thread;
 	struct perf_event_attr *attr = &evsel->attr;
@@ -1425,44 +1458,44 @@ static void process_event(struct perf_script *script,
 	if (output[type].fields == 0)
 		return;
 
-	fprint_sample_start(sample, thread, evsel, stdout);
+	evsel->samples++;
+	fprint_sample_start(sample, thread, evsel, fp);
 
 	if (PRINT_FIELD(PERIOD))
-		fprintf(stdout, "%10" PRIu64 " ", sample->period);
+		fprintf(fp, "%10" PRIu64 " ", sample->period);
 
 	if (PRINT_FIELD(EVNAME)) {
 		const char *evname = perf_evsel__name(evsel);
-
 		if (!script->name_width)
 			script->name_width = perf_evlist__max_name_len(script->session->evlist);
 
-		fprintf(stdout, "%*s: ", script->name_width,
+		fprintf(fp, "%*s: ", script->name_width,
 		       evname ? evname : "[unknown]");
 	}
 
 	if (print_flags)
-		fprint_sample_flags(sample->flags, stdout);
+		fprint_sample_flags(sample->flags, fp);
 
 	if (is_bts_event(attr)) {
-		fprint_sample_bts(sample, evsel, thread, al, machine, stdout);
+		fprint_sample_bts(sample, evsel, thread, al, machine, fp);
 		return;
 	}
 
 	if (PRINT_FIELD(TRACE))
 		event_format__fprintf(evsel->tp_format, sample->cpu,
-				    sample->raw_data, sample->raw_size, stdout);
+				    sample->raw_data, sample->raw_size, fp);
 
 	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
-		fprint_sample_synth(sample, evsel, stdout);
+		fprint_sample_synth(sample, evsel, fp);
 
 	if (PRINT_FIELD(ADDR))
-		fprint_sample_addr(sample, thread, attr, stdout);
+		fprint_sample_addr(sample, thread, attr, fp);
 
 	if (PRINT_FIELD(DATA_SRC))
-		data_src__fprintf(sample->data_src, stdout);
+		data_src__fprintf(sample->data_src, fp);
 
 	if (PRINT_FIELD(WEIGHT))
-		fprintf(stdout, "%16" PRIu64, sample->weight);
+		fprintf(fp, "%16" PRIu64, sample->weight);
 
 	if (PRINT_FIELD(IP)) {
 		struct callchain_cursor *cursor = NULL;
@@ -1472,30 +1505,30 @@ static void process_event(struct perf_script *script,
 					      sample, NULL, NULL, scripting_max_stack) == 0)
 			cursor = &callchain_cursor;
 
-		fputc(cursor ? '\n' : ' ', stdout);
-		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, stdout);
+		fputc(cursor ? '\n' : ' ', fp);
+		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp);
 	}
 
 	if (PRINT_FIELD(IREGS))
-		fprint_sample_iregs(sample, attr, stdout);
+		fprint_sample_iregs(sample, attr, fp);
 
 	if (PRINT_FIELD(UREGS))
-		fprint_sample_uregs(sample, attr, stdout);
+		fprint_sample_uregs(sample, attr, fp);
 
 	if (PRINT_FIELD(BRSTACK))
-		fprint_sample_brstack(sample, thread, attr, stdout);
+		fprint_sample_brstack(sample, thread, attr, fp);
 	else if (PRINT_FIELD(BRSTACKSYM))
-		fprint_sample_brstacksym(sample, thread, attr, stdout);
+		fprint_sample_brstacksym(sample, thread, attr, fp);
 	else if (PRINT_FIELD(BRSTACKOFF))
-		fprint_sample_brstackoff(sample, thread, attr, stdout);
+		fprint_sample_brstackoff(sample, thread, attr, fp);
 
 	if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
-		fprint_sample_bpf_output(sample, stdout);
-	fprint_insn(sample, attr, thread, machine, stdout);
+		fprint_sample_bpf_output(sample, fp);
+	fprint_insn(sample, attr, thread, machine, fp);
 
 	if (PRINT_FIELD(PHYS_ADDR))
-		fprintf(stdout, "%16" PRIx64, sample->phys_addr);
-	fprintf(stdout, "\n");
+		fprintf(fp, "%16" PRIx64, sample->phys_addr);
+	fprintf(fp, "\n");
 }
 
 static struct scripting_ops	*scripting_ops;
@@ -1574,6 +1607,7 @@ static int process_sample_event(struct perf_tool *tool,
 {
 	struct perf_script *scr = container_of(tool, struct perf_script, tool);
 	struct addr_location al;
+	FILE *fp;
 
 	if (perf_time__skip_sample(&scr->ptime, sample->time))
 		return 0;
@@ -1601,10 +1635,11 @@ static int process_sample_event(struct perf_tool *tool,
 	if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
 		goto out_put;
 
+	fp = fp_selection_helper(scr, evsel);
 	if (scripting_ops)
 		scripting_ops->process_event(event, sample, evsel, &al);
 	else
-		process_event(scr, sample, evsel, &al, machine, stdout);
+		process_event(scr, sample, evsel, &al, machine, fp);
 
 out_put:
 	addr_location__put(&al);
@@ -1653,6 +1688,7 @@ static int process_comm_event(struct perf_tool *tool,
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 	int ret = -1;
+	FILE *fp;
 
 	thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
 	if (thread == NULL) {
@@ -1669,8 +1705,9 @@ static int process_comm_event(struct perf_tool *tool,
 		sample->tid = event->comm.tid;
 		sample->pid = event->comm.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	ret = 0;
 out:
 	thread__put(thread);
@@ -1687,6 +1724,7 @@ static int process_namespaces_event(struct perf_tool *tool,
 	struct perf_session *session = script->session;
 	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 	int ret = -1;
+	FILE *fp;
 
 	thread = machine__findnew_thread(machine, event->namespaces.pid,
 					 event->namespaces.tid);
@@ -1704,8 +1742,9 @@ static int process_namespaces_event(struct perf_tool *tool,
 		sample->tid = event->namespaces.tid;
 		sample->pid = event->namespaces.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	ret = 0;
 out:
 	thread__put(thread);
@@ -1721,6 +1760,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;
@@ -1737,8 +1777,9 @@ static int process_fork_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 
 	return 0;
@@ -1753,6 +1794,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) {
@@ -1766,8 +1808,9 @@ static int process_exit_event(struct perf_tool *tool,
 		sample->tid = event->fork.tid;
 		sample->pid = event->fork.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 
 	if (perf_event__process_exit(tool, event, sample, machine) < 0)
 		err = -1;
@@ -1785,6 +1828,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;
@@ -1801,8 +1845,9 @@ static int process_mmap_event(struct perf_tool *tool,
 		sample->tid = event->mmap.tid;
 		sample->pid = event->mmap.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 	return 0;
 }
@@ -1816,6 +1861,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;
@@ -1832,8 +1878,9 @@ static int process_mmap2_event(struct perf_tool *tool,
 		sample->tid = event->mmap2.tid;
 		sample->pid = event->mmap2.pid;
 	}
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_start(sample, thread, evsel, fp);
+	perf_event__fprintf(event, fp);
 	thread__put(thread);
 	return 0;
 }
@@ -1847,6 +1894,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;
@@ -1857,9 +1905,9 @@ static int process_switch_event(struct perf_tool *tool,
 		pr_debug("problem processing SWITCH event, skipping it.\n");
 		return -1;
 	}
-
-	fprint_sample_start(sample, thread, evsel, stdout);
-	perf_event__fprintf(event, stdout);
+	fp = fp_selection_helper(script, evsel);
+	fprint_sample_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 ceac084..8a2cd96 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"
@@ -1826,6 +1828,8 @@ 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;
 	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;
@@ -1833,6 +1837,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);
@@ -1918,7 +1923,6 @@ static int __perf_session__process_events(struct perf_session *session,
 
 	if (file_pos < file_size)
 		goto more;
-
 out:
 	/* do the final flush for ordered samples */
 	err = ordered_events__flush(oe, OE_FLUSH__FINAL);
@@ -1938,6 +1942,16 @@ 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) {
+			stat(evsel->filename, &statbuf);
+			fprintf(stderr,	"[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
+				statbuf.st_size / 1024.0 / 1024.0, evsel->filename, evsel->samples);
+			fclose(evsel->dump_event_fp);
+			free(evsel->filename);
+		}
+	}
 	return err;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/4] Add fp argument to print functions
  2017-10-11 18:23 ` [PATCH v3 2/4] Add fp argument to print functions ufo19890607
@ 2017-10-17 14:01   ` Arnaldo Carvalho de Melo
       [not found]     ` <CAHCio2ggZapg7KvWOO3OonFTHq5CZ02c2sghTpP73QBJ0mi9jg@mail.gmail.com>
  0 siblings, 1 reply; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-10-17 14:01 UTC (permalink / raw)
  To: ufo19890607
  Cc: peterz, mingo, alexander.shishkin, jolsa, dsahern, namhyung,
	milian.wolff, arnaldo.melo, yuzhoujian, linux-perf-users,
	linux-kernel

Em Thu, Oct 12, 2017 at 02:23:58AM +0800, ufo19890607 escreveu:
> From: yuzhoujian <yuzhoujian@didichuxing.com>
> 
> This patch will add the fp argument to all the print functions so that they can use different
> file pointer to print on the screen or dump in the file.
> 
> Changes since v2:
> - none
> 
> Changes since v1:
> - add the __maybe_unused attribute for the fp argument in all the print functions,
>  because the fp is not used in this patch but needed in the later patches.
> - split the original patch(Makes all those related functions receive the FILE
>  pointer) to two simple patches, and this is the first part.

Please take a look at my perf/core branch, I've implemented it as I
suggested, no __maybe_unused was needed, as we go using it straight
away, just passing stdout for now.

More specifically:

https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/commit/?h=perf/core&id=817d5c11c31c7459d4bd6c5ccbd6ada455c595b2

I'll look at the other patches soon,

- Arnaldo
 
> Signed-off-by: yuzhoujian <yuzhoujian@didichuxing.com>
> ---
>  tools/perf/builtin-script.c | 190 +++++++++++++++++++++++---------------------
>  1 file changed, 100 insertions(+), 90 deletions(-)
> 
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 4ffa716..4b51dd1 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -500,8 +500,8 @@ static int perf_session__check_output_opt(struct perf_session *session)
>  	return 0;
>  }
>  
> -static void print_sample_iregs(struct perf_sample *sample,
> -			  struct perf_event_attr *attr)
> +static void fprint_sample_iregs(struct perf_sample *sample,
> +			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
>  {
>  	struct regs_dump *regs = &sample->intr_regs;
>  	uint64_t mask = attr->sample_regs_intr;
> @@ -516,8 +516,8 @@ static void print_sample_iregs(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_uregs(struct perf_sample *sample,
> -			  struct perf_event_attr *attr)
> +static void fprint_sample_uregs(struct perf_sample *sample,
> +			  struct perf_event_attr *attr, FILE *fp __maybe_unused)
>  {
>  	struct regs_dump *regs = &sample->user_regs;
>  	uint64_t mask = attr->sample_regs_user;
> @@ -534,9 +534,9 @@ static void print_sample_uregs(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_start(struct perf_sample *sample,
> +static void fprint_sample_start(struct perf_sample *sample,
>  			       struct thread *thread,
> -			       struct perf_evsel *evsel)
> +			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
>  {
>  	struct perf_event_attr *attr = &evsel->attr;
>  	unsigned long secs;
> @@ -589,9 +589,10 @@ static void print_sample_start(struct perf_sample *sample,
>  	return br->flags.predicted ? 'P' : 'M';
>  }
>  
> -static void print_sample_brstack(struct perf_sample *sample,
> +static void fprint_sample_brstack(struct perf_sample *sample,
>  				 struct thread *thread,
> -				 struct perf_event_attr *attr)
> +				 struct perf_event_attr *attr,
> +				 FILE *fp __maybe_unused)
>  {
>  	struct branch_stack *br = sample->branch_stack;
>  	struct addr_location alf, alt;
> @@ -633,9 +634,10 @@ static void print_sample_brstack(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_brstacksym(struct perf_sample *sample,
> +static void fprint_sample_brstacksym(struct perf_sample *sample,
>  				    struct thread *thread,
> -				    struct perf_event_attr *attr)
> +				    struct perf_event_attr *attr,
> +				    FILE *fp __maybe_unused)
>  {
>  	struct branch_stack *br = sample->branch_stack;
>  	struct addr_location alf, alt;
> @@ -680,9 +682,10 @@ static void print_sample_brstacksym(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_brstackoff(struct perf_sample *sample,
> +static void fprint_sample_brstackoff(struct perf_sample *sample,
>  				    struct thread *thread,
> -				    struct perf_event_attr *attr)
> +				    struct perf_event_attr *attr,
> +				    FILE *fp __maybe_unused)
>  {
>  	struct branch_stack *br = sample->branch_stack;
>  	struct addr_location alf, alt;
> @@ -789,9 +792,9 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
>  	return len;
>  }
>  
> -static void print_jump(uint64_t ip, struct branch_entry *en,
> +static void fprint_jump(uint64_t ip, struct branch_entry *en,
>  		       struct perf_insn *x, u8 *inbuf, int len,
> -		       int insn)
> +		       int insn, FILE *fp __maybe_unused)
>  {
>  	printf("\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
>  	       ip,
> @@ -808,9 +811,10 @@ static void print_jump(uint64_t ip, struct branch_entry *en,
>  	putchar('\n');
>  }
>  
> -static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
> +static void fprint_ip_sym(struct thread *thread, u8 cpumode, int cpu,
>  			 uint64_t addr, struct symbol **lastsym,
> -			 struct perf_event_attr *attr)
> +			 struct perf_event_attr *attr,
> +			 FILE *fp __maybe_unused)
>  {
>  	struct addr_location al;
>  	int off;
> @@ -846,10 +850,11 @@ static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
>  	*lastsym = al.sym;
>  }
>  
> -static void print_sample_brstackinsn(struct perf_sample *sample,
> +static void fprint_sample_brstackinsn(struct perf_sample *sample,
>  				     struct thread *thread,
>  				     struct perf_event_attr *attr,
> -				     struct machine *machine)
> +				     struct machine *machine,
> +				     FILE *fp __maybe_unused)
>  {
>  	struct branch_stack *br = sample->branch_stack;
>  	u64 start, end;
> @@ -875,10 +880,10 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
>  			br->entries[nr-1].from,
>  			machine, thread, &x.is64bit, &x.cpumode, false);
>  	if (len > 0) {
> -		print_ip_sym(thread, x.cpumode, x.cpu,
> -			     br->entries[nr - 1].from, &lastsym, attr);
> -		print_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
> -			    &x, buffer, len, 0);
> +		fprint_ip_sym(thread, x.cpumode, x.cpu,
> +			     br->entries[nr - 1].from, &lastsym, attr, stdout);
> +		fprint_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
> +			    &x, buffer, len, 0, stdout);
>  	}
>  
>  	/* Print all blocks */
> @@ -904,9 +909,9 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
>  		for (off = 0;; off += ilen) {
>  			uint64_t ip = start + off;
>  
> -			print_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr);
> +			fprint_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr, stdout);
>  			if (ip == end) {
> -				print_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn);
> +				fprint_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, stdout);
>  				break;
>  			} else {
>  				printf("\t%016" PRIx64 "\t%s\n", ip,
> @@ -933,7 +938,7 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
>  	start = br->entries[0].to;
>  	end = sample->ip;
>  	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
> -	print_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr);
> +	fprint_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr, stdout);
>  	if (len <= 0) {
>  		/* Print at least last IP if basic block did not work */
>  		len = grab_bb(buffer, sample->ip, sample->ip,
> @@ -953,9 +958,10 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_addr(struct perf_sample *sample,
> +static void fprint_sample_addr(struct perf_sample *sample,
>  			  struct thread *thread,
> -			  struct perf_event_attr *attr)
> +			  struct perf_event_attr *attr,
> +			  FILE *fp __maybe_unused)
>  {
>  	struct addr_location al;
>  
> @@ -981,10 +987,11 @@ static void print_sample_addr(struct perf_sample *sample,
>  	}
>  }
>  
> -static void print_sample_callindent(struct perf_sample *sample,
> +static void fprint_sample_callindent(struct perf_sample *sample,
>  				    struct perf_evsel *evsel,
>  				    struct thread *thread,
> -				    struct addr_location *al)
> +				    struct addr_location *al,
> +				    FILE *fp __maybe_unused)
>  {
>  	struct perf_event_attr *attr = &evsel->attr;
>  	size_t depth = thread_stack__depth(thread);
> @@ -1037,10 +1044,11 @@ static void print_sample_callindent(struct perf_sample *sample,
>  		printf("%*s", spacing - len, "");
>  }
>  
> -static void print_insn(struct perf_sample *sample,
> +static void fprint_insn(struct perf_sample *sample,
>  		       struct perf_event_attr *attr,
>  		       struct thread *thread,
> -		       struct machine *machine)
> +		       struct machine *machine,
> +		       FILE *fp __maybe_unused)
>  {
>  	if (PRINT_FIELD(INSNLEN))
>  		printf(" ilen: %d", sample->insn_len);
> @@ -1052,21 +1060,22 @@ static void print_insn(struct perf_sample *sample,
>  			printf(" %02x", (unsigned char)sample->insn[i]);
>  	}
>  	if (PRINT_FIELD(BRSTACKINSN))
> -		print_sample_brstackinsn(sample, thread, attr, machine);
> +		fprint_sample_brstackinsn(sample, thread, attr, machine, stdout);
>  }
>  
> -static void print_sample_bts(struct perf_sample *sample,
> +static void fprint_sample_bts(struct perf_sample *sample,
>  			     struct perf_evsel *evsel,
>  			     struct thread *thread,
>  			     struct addr_location *al,
> -			     struct machine *machine)
> +			     struct machine *machine,
> +			     FILE *fp __maybe_unused)
>  {
>  	struct perf_event_attr *attr = &evsel->attr;
>  	unsigned int type = output_type(attr->type);
>  	bool print_srcline_last = false;
>  
>  	if (PRINT_FIELD(CALLINDENT))
> -		print_sample_callindent(sample, evsel, thread, al);
> +		fprint_sample_callindent(sample, evsel, thread, al, stdout);
>  
>  	/* print branch_from information */
>  	if (PRINT_FIELD(IP)) {
> @@ -1095,13 +1104,13 @@ static void print_sample_bts(struct perf_sample *sample,
>  	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
>  	     !output[type].user_set)) {
>  		printf(" => ");
> -		print_sample_addr(sample, thread, attr);
> +		fprint_sample_addr(sample, thread, attr, stdout);
>  	}
>  
>  	if (print_srcline_last)
>  		map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
>  
> -	print_insn(sample, attr, thread, machine);
> +	fprint_insn(sample, attr, thread, machine, stdout);
>  
>  	printf("\n");
>  }
> @@ -1126,7 +1135,7 @@ static void print_sample_bts(struct perf_sample *sample,
>  	{0, NULL}
>  };
>  
> -static void print_sample_flags(u32 flags)
> +static void fprint_sample_flags(u32 flags, FILE *fp __maybe_unused)
>  {
>  	const char *chars = PERF_IP_FLAG_CHARS;
>  	const int n = strlen(PERF_IP_FLAG_CHARS);
> @@ -1162,10 +1171,11 @@ struct printer_data {
>  	int line_no;
>  	bool hit_nul;
>  	bool is_printable;
> +	FILE *fp;
>  };
>  
>  static void
> -print_sample_bpf_output_printer(enum binary_printer_ops op,
> +fprint_sample_bpf_output_printer(enum binary_printer_ops op,
>  				unsigned int val,
>  				void *extra)
>  {
> @@ -1223,31 +1233,31 @@ struct printer_data {
>  	}
>  }
>  
> -static void print_sample_bpf_output(struct perf_sample *sample)
> +static void fprint_sample_bpf_output(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	unsigned int nr_bytes = sample->raw_size;
> -	struct printer_data printer_data = {0, false, true};
> +	struct printer_data printer_data = {0, false, true, stdout};
>  
>  	print_binary(sample->raw_data, nr_bytes, 8,
> -		     print_sample_bpf_output_printer, &printer_data);
> +		     fprint_sample_bpf_output_printer, &printer_data);
>  
>  	if (printer_data.is_printable && printer_data.hit_nul)
>  		printf("%17s \"%s\"\n", "BPF string:",
>  		       (char *)(sample->raw_data));
>  }
>  
> -static void print_sample_spacing(int len, int spacing)
> +static void fprint_sample_spacing(int len, int spacing, FILE *fp __maybe_unused)
>  {
>  	if (len > 0 && len < spacing)
>  		printf("%*s", spacing - len, "");
>  }
>  
> -static void print_sample_pt_spacing(int len)
> +static void fprint_sample_pt_spacing(int len, FILE *fp __maybe_unused)
>  {
> -	print_sample_spacing(len, 34);
> +	fprint_sample_spacing(len, 34, stdout);
>  }
>  
> -static void print_sample_synth_ptwrite(struct perf_sample *sample)
> +static void fprint_sample_synth_ptwrite(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
>  	int len;
> @@ -1257,10 +1267,10 @@ static void print_sample_synth_ptwrite(struct perf_sample *sample)
>  
>  	len = printf(" IP: %u payload: %#" PRIx64 " ",
>  		     data->ip, le64_to_cpu(data->payload));
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth_mwait(struct perf_sample *sample)
> +static void fprint_sample_synth_mwait(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
>  	int len;
> @@ -1270,10 +1280,10 @@ static void print_sample_synth_mwait(struct perf_sample *sample)
>  
>  	len = printf(" hints: %#x extensions: %#x ",
>  		     data->hints, data->extensions);
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth_pwre(struct perf_sample *sample)
> +static void fprint_sample_synth_pwre(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
>  	int len;
> @@ -1283,10 +1293,10 @@ static void print_sample_synth_pwre(struct perf_sample *sample)
>  
>  	len = printf(" hw: %u cstate: %u sub-cstate: %u ",
>  		     data->hw, data->cstate, data->subcstate);
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth_exstop(struct perf_sample *sample)
> +static void fprint_sample_synth_exstop(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
>  	int len;
> @@ -1295,10 +1305,10 @@ static void print_sample_synth_exstop(struct perf_sample *sample)
>  		return;
>  
>  	len = printf(" IP: %u ", data->ip);
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth_pwrx(struct perf_sample *sample)
> +static void fprint_sample_synth_pwrx(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
>  	int len;
> @@ -1309,10 +1319,10 @@ static void print_sample_synth_pwrx(struct perf_sample *sample)
>  	len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ",
>  		     data->deepest_cstate, data->last_cstate,
>  		     data->wake_reason);
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth_cbr(struct perf_sample *sample)
> +static void fprint_sample_synth_cbr(struct perf_sample *sample, FILE *fp __maybe_unused)
>  {
>  	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
>  	unsigned int percent, freq;
> @@ -1327,30 +1337,30 @@ static void print_sample_synth_cbr(struct perf_sample *sample)
>  		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
>  		len += printf("(%3u%%) ", percent);
>  	}
> -	print_sample_pt_spacing(len);
> +	fprint_sample_pt_spacing(len, stdout);
>  }
>  
> -static void print_sample_synth(struct perf_sample *sample,
> -			       struct perf_evsel *evsel)
> +static void fprint_sample_synth(struct perf_sample *sample,
> +			       struct perf_evsel *evsel, FILE *fp __maybe_unused)
>  {
>  	switch (evsel->attr.config) {
>  	case PERF_SYNTH_INTEL_PTWRITE:
> -		print_sample_synth_ptwrite(sample);
> +		fprint_sample_synth_ptwrite(sample, stdout);
>  		break;
>  	case PERF_SYNTH_INTEL_MWAIT:
> -		print_sample_synth_mwait(sample);
> +		fprint_sample_synth_mwait(sample, stdout);
>  		break;
>  	case PERF_SYNTH_INTEL_PWRE:
> -		print_sample_synth_pwre(sample);
> +		fprint_sample_synth_pwre(sample, stdout);
>  		break;
>  	case PERF_SYNTH_INTEL_EXSTOP:
> -		print_sample_synth_exstop(sample);
> +		fprint_sample_synth_exstop(sample, stdout);
>  		break;
>  	case PERF_SYNTH_INTEL_PWRX:
> -		print_sample_synth_pwrx(sample);
> +		fprint_sample_synth_pwrx(sample, stdout);
>  		break;
>  	case PERF_SYNTH_INTEL_CBR:
> -		print_sample_synth_cbr(sample);
> +		fprint_sample_synth_cbr(sample, stdout);
>  		break;
>  	default:
>  		break;
> @@ -1386,7 +1396,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
>  	return max;
>  }
>  
> -static size_t data_src__printf(u64 data_src)
> +static size_t data_src__fprintf(u64 data_src, FILE *fp __maybe_unused)
>  {
>  	struct mem_info mi = { .data_src.val = data_src };
>  	char decode[100];
> @@ -1406,7 +1416,7 @@ static size_t data_src__printf(u64 data_src)
>  static void process_event(struct perf_script *script,
>  			  struct perf_sample *sample, struct perf_evsel *evsel,
>  			  struct addr_location *al,
> -			  struct machine *machine)
> +			  struct machine *machine, FILE *fp __maybe_unused)
>  {
>  	struct thread *thread = al->thread;
>  	struct perf_event_attr *attr = &evsel->attr;
> @@ -1415,7 +1425,7 @@ static void process_event(struct perf_script *script,
>  	if (output[type].fields == 0)
>  		return;
>  
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  
>  	if (PRINT_FIELD(PERIOD))
>  		printf("%10" PRIu64 " ", sample->period);
> @@ -1431,25 +1441,25 @@ static void process_event(struct perf_script *script,
>  	}
>  
>  	if (print_flags)
> -		print_sample_flags(sample->flags);
> +		fprint_sample_flags(sample->flags, stdout);
>  
>  	if (is_bts_event(attr)) {
> -		print_sample_bts(sample, evsel, thread, al, machine);
> +		fprint_sample_bts(sample, evsel, thread, al, machine, stdout);
>  		return;
>  	}
>  
>  	if (PRINT_FIELD(TRACE))
> -		event_format__print(evsel->tp_format, sample->cpu,
> -				    sample->raw_data, sample->raw_size);
> +		event_format__fprintf(evsel->tp_format, sample->cpu,
> +				    sample->raw_data, sample->raw_size, stdout);
>  
>  	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
> -		print_sample_synth(sample, evsel);
> +		fprint_sample_synth(sample, evsel, stdout);
>  
>  	if (PRINT_FIELD(ADDR))
> -		print_sample_addr(sample, thread, attr);
> +		fprint_sample_addr(sample, thread, attr, stdout);
>  
>  	if (PRINT_FIELD(DATA_SRC))
> -		data_src__printf(sample->data_src);
> +		data_src__fprintf(sample->data_src, stdout);
>  
>  	if (PRINT_FIELD(WEIGHT))
>  		printf("%16" PRIu64, sample->weight);
> @@ -1467,21 +1477,21 @@ static void process_event(struct perf_script *script,
>  	}
>  
>  	if (PRINT_FIELD(IREGS))
> -		print_sample_iregs(sample, attr);
> +		fprint_sample_iregs(sample, attr, stdout);
>  
>  	if (PRINT_FIELD(UREGS))
> -		print_sample_uregs(sample, attr);
> +		fprint_sample_uregs(sample, attr, stdout);
>  
>  	if (PRINT_FIELD(BRSTACK))
> -		print_sample_brstack(sample, thread, attr);
> +		fprint_sample_brstack(sample, thread, attr, stdout);
>  	else if (PRINT_FIELD(BRSTACKSYM))
> -		print_sample_brstacksym(sample, thread, attr);
> +		fprint_sample_brstacksym(sample, thread, attr, stdout);
>  	else if (PRINT_FIELD(BRSTACKOFF))
> -		print_sample_brstackoff(sample, thread, attr);
> +		fprint_sample_brstackoff(sample, thread, attr, stdout);
>  
>  	if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
> -		print_sample_bpf_output(sample);
> -	print_insn(sample, attr, thread, machine);
> +		fprint_sample_bpf_output(sample, stdout);
> +	fprint_insn(sample, attr, thread, machine, stdout);
>  
>  	if (PRINT_FIELD(PHYS_ADDR))
>  		printf("%16" PRIx64, sample->phys_addr);
> @@ -1594,7 +1604,7 @@ static int process_sample_event(struct perf_tool *tool,
>  	if (scripting_ops)
>  		scripting_ops->process_event(event, sample, evsel, &al);
>  	else
> -		process_event(scr, sample, evsel, &al, machine);
> +		process_event(scr, sample, evsel, &al, machine, stdout);
>  
>  out_put:
>  	addr_location__put(&al);
> @@ -1659,7 +1669,7 @@ static int process_comm_event(struct perf_tool *tool,
>  		sample->tid = event->comm.tid;
>  		sample->pid = event->comm.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	ret = 0;
>  out:
> @@ -1694,7 +1704,7 @@ static int process_namespaces_event(struct perf_tool *tool,
>  		sample->tid = event->namespaces.tid;
>  		sample->pid = event->namespaces.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	ret = 0;
>  out:
> @@ -1727,7 +1737,7 @@ static int process_fork_event(struct perf_tool *tool,
>  		sample->tid = event->fork.tid;
>  		sample->pid = event->fork.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	thread__put(thread);
>  
> @@ -1756,7 +1766,7 @@ static int process_exit_event(struct perf_tool *tool,
>  		sample->tid = event->fork.tid;
>  		sample->pid = event->fork.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  
>  	if (perf_event__process_exit(tool, event, sample, machine) < 0)
> @@ -1791,7 +1801,7 @@ static int process_mmap_event(struct perf_tool *tool,
>  		sample->tid = event->mmap.tid;
>  		sample->pid = event->mmap.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	thread__put(thread);
>  	return 0;
> @@ -1822,7 +1832,7 @@ static int process_mmap2_event(struct perf_tool *tool,
>  		sample->tid = event->mmap2.tid;
>  		sample->pid = event->mmap2.pid;
>  	}
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	thread__put(thread);
>  	return 0;
> @@ -1848,7 +1858,7 @@ static int process_switch_event(struct perf_tool *tool,
>  		return -1;
>  	}
>  
> -	print_sample_start(sample, thread, evsel);
> +	fprint_sample_start(sample, thread, evsel, stdout);
>  	perf_event__fprintf(event, stdout);
>  	thread__put(thread);
>  	return 0;
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/4] Add fp argument to print functions
       [not found]     ` <CAHCio2ggZapg7KvWOO3OonFTHq5CZ02c2sghTpP73QBJ0mi9jg@mail.gmail.com>
@ 2017-10-18 12:22       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-10-18 12:22 UTC (permalink / raw)
  To: 禹舟键
  Cc: Arnaldo Carvalho de Melo, peterz, mingo, alexander.shishkin,
	jolsa, David Ahern, Namhyung Kim, Milian Wolff, Wind Yu,
	linux-perf-users, linux-kernel

Em Wed, Oct 18, 2017 at 07:54:13PM +0800, 禹舟键 escreveu:
> Hi, Arnaldo
> I have done it as you said in v1 patch, but David had told me to separate
> the patch :"Makes all those related functions receive the FILE pointer"  to
> two patches. Below is his opinion.
> 
> On 9/13/17 9:10 AM, yuzhoujian wrote:
> > @@ -1621,8 +1634,12 @@ static int process_comm_event(struct perf_tool
> *tool,
> >               sample->tid = event->comm.tid;
> >               sample->pid = event->comm.pid;
> >       }
> > -     print_sample_start(sample, thread, evsel);
> > -     perf_event__fprintf(event, stdout);
> > +     if (tool->orientation_output == false)
> > +             fp = stdout;
> > +     else
> > +             fp = orientation_file;
> > +     fprint_sample_start(sample, thread, evsel, fp);
> > +     perf_event__fprintf(event, fp);
> >       ret = 0;
> >  out:
> >       thread__put(thread);
> 
> "The subject of this patch is replacing printf and stdout with fprintf
> and a given fp. Please keep it to that one change. Meaning the above
> setting of fp something other than stdout should be a separate patch.

I have done exactly as described in my and David's suggestion, this
"orientation_file" change is not in my patch.

> And it would be best to have the fp selection in a helper, versus the
> same change in so many places. "
> 
> So, what should I do??

Please consider continuing from the other suggestion I made in a recent
message, about how to use evsel->priv to store the perf evsel FILE
pointer.

- Arnaldo

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-10-18 12:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11 18:23 [PATCH v3 0/4] perf script: Add script per-event-dump support ufo19890607
2017-10-11 18:23 ` [PATCH v3 1/4] Add two elements for perf_tool struct, and add three elements for perf_evsel struct, and add the per-event-dump option for perf script ufo19890607
2017-10-11 18:23 ` [PATCH v3 2/4] Add fp argument to print functions ufo19890607
2017-10-17 14:01   ` Arnaldo Carvalho de Melo
     [not found]     ` <CAHCio2ggZapg7KvWOO3OonFTHq5CZ02c2sghTpP73QBJ0mi9jg@mail.gmail.com>
2017-10-18 12:22       ` Arnaldo Carvalho de Melo
2017-10-11 18:23 ` [PATCH v3 3/4] Replace printf with fprintf for all " ufo19890607
2017-10-11 18:24 ` [PATCH v3 4/4] Make all print functions receive the fp argument, open and close the dump_event file for each evsel, and calculate the dump_event file's size ufo19890607

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).