diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
| -rw-r--r-- | tools/perf/builtin-script.c | 127 | 
1 files changed, 89 insertions, 38 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9c333ff3dfeb..baf17989a216 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -15,6 +15,7 @@  #include "util/evlist.h"  #include "util/evsel.h"  #include "util/sort.h" +#include "util/data.h"  #include <linux/bitmap.h>  static char const		*script_name; @@ -228,6 +229,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,  	return 0;  } +static void set_print_ip_opts(struct perf_event_attr *attr) +{ +	unsigned int type = attr->type; + +	output[type].print_ip_opts = 0; +	if (PRINT_FIELD(IP)) +		output[type].print_ip_opts |= PRINT_IP_OPT_IP; + +	if (PRINT_FIELD(SYM)) +		output[type].print_ip_opts |= PRINT_IP_OPT_SYM; + +	if (PRINT_FIELD(DSO)) +		output[type].print_ip_opts |= PRINT_IP_OPT_DSO; + +	if (PRINT_FIELD(SYMOFFSET)) +		output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET; +} +  /*   * verify all user requested events exist and the samples   * have the expected data @@ -236,7 +255,6 @@ static int perf_session__check_output_opt(struct perf_session *session)  {  	int j;  	struct perf_evsel *evsel; -	struct perf_event_attr *attr;  	for (j = 0; j < PERF_TYPE_MAX; ++j) {  		evsel = perf_session__find_first_evtype(session, j); @@ -259,20 +277,7 @@ static int perf_session__check_output_opt(struct perf_session *session)  		if (evsel == NULL)  			continue; -		attr = &evsel->attr; - -		output[j].print_ip_opts = 0; -		if (PRINT_FIELD(IP)) -			output[j].print_ip_opts |= PRINT_IP_OPT_IP; - -		if (PRINT_FIELD(SYM)) -			output[j].print_ip_opts |= PRINT_IP_OPT_SYM; - -		if (PRINT_FIELD(DSO)) -			output[j].print_ip_opts |= PRINT_IP_OPT_DSO; - -		if (PRINT_FIELD(SYMOFFSET)) -			output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET; +		set_print_ip_opts(&evsel->attr);  	}  	return 0; @@ -290,11 +295,11 @@ static void print_sample_start(struct perf_sample *sample,  	if (PRINT_FIELD(COMM)) {  		if (latency_format) -			printf("%8.8s ", thread->comm); +			printf("%8.8s ", thread__comm_str(thread));  		else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) -			printf("%s ", thread->comm); +			printf("%s ", thread__comm_str(thread));  		else -			printf("%16s ", thread->comm); +			printf("%16s ", thread__comm_str(thread));  	}  	if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) @@ -409,7 +414,9 @@ static void print_sample_bts(union perf_event *event,  	printf(" => ");  	/* print branch_to information */ -	if (PRINT_FIELD(ADDR)) +	if (PRINT_FIELD(ADDR) || +	    ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && +	     !output[attr->type].user_set))  		print_sample_addr(event, sample, machine, thread, attr);  	printf("\n"); @@ -539,32 +546,51 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,  	return 0;  } -static struct perf_tool perf_script = { -	.sample		 = process_sample_event, -	.mmap		 = perf_event__process_mmap, -	.mmap2		 = perf_event__process_mmap2, -	.comm		 = perf_event__process_comm, -	.exit		 = perf_event__process_exit, -	.fork		 = perf_event__process_fork, -	.attr		 = perf_event__process_attr, -	.tracing_data	 = perf_event__process_tracing_data, -	.build_id	 = perf_event__process_build_id, -	.ordered_samples = true, -	.ordering_requires_timestamps = true, +struct perf_script { +	struct perf_tool	tool; +	struct perf_session	*session;  }; +static int process_attr(struct perf_tool *tool, union perf_event *event, +			struct perf_evlist **pevlist) +{ +	struct perf_script *scr = container_of(tool, struct perf_script, tool); +	struct perf_evlist *evlist; +	struct perf_evsel *evsel, *pos; +	int err; + +	err = perf_event__process_attr(tool, event, pevlist); +	if (err) +		return err; + +	evlist = *pevlist; +	evsel = perf_evlist__last(*pevlist); + +	if (evsel->attr.type >= PERF_TYPE_MAX) +		return 0; + +	list_for_each_entry(pos, &evlist->entries, node) { +		if (pos->attr.type == evsel->attr.type && pos != evsel) +			return 0; +	} + +	set_print_ip_opts(&evsel->attr); + +	return perf_evsel__check_attr(evsel, scr->session); +} +  static void sig_handler(int sig __maybe_unused)  {  	session_done = 1;  } -static int __cmd_script(struct perf_session *session) +static int __cmd_script(struct perf_script *script)  {  	int ret;  	signal(SIGINT, sig_handler); -	ret = perf_session__process_events(session, &perf_script); +	ret = perf_session__process_events(script->session, &script->tool);  	if (debug_mode)  		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); @@ -1113,10 +1139,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)  	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];  	DIR *scripts_dir, *lang_dir;  	struct perf_session *session; +	struct perf_data_file file = { +		.path = input_name, +		.mode = PERF_DATA_MODE_READ, +	};  	char *temp;  	int i = 0; -	session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); +	session = perf_session__new(&file, false, NULL);  	if (!session)  		return -1; @@ -1266,6 +1296,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  	char *script_path = NULL;  	const char **__argv;  	int i, j, err; +	struct perf_script script = { +		.tool = { +			.sample		 = process_sample_event, +			.mmap		 = perf_event__process_mmap, +			.mmap2		 = perf_event__process_mmap2, +			.comm		 = perf_event__process_comm, +			.exit		 = perf_event__process_exit, +			.fork		 = perf_event__process_fork, +			.attr		 = process_attr, +			.tracing_data	 = perf_event__process_tracing_data, +			.build_id	 = perf_event__process_build_id, +			.ordered_samples = true, +			.ordering_requires_timestamps = true, +		}, +	};  	const struct option options[] = {  	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,  		    "dump raw trace in ASCII"), @@ -1317,12 +1362,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  		"perf script [<options>] <top-script> [script-args]",  		NULL  	}; +	struct perf_data_file file = { +		.mode = PERF_DATA_MODE_READ, +	};  	setup_scripting();  	argc = parse_options(argc, argv, options, script_usage,  			     PARSE_OPT_STOP_AT_NON_OPTION); +	file.path = input_name; +  	if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {  		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);  		if (!rec_script_path) @@ -1486,11 +1536,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  	if (!script_name)  		setup_pager(); -	session = perf_session__new(input_name, O_RDONLY, 0, false, -				    &perf_script); +	session = perf_session__new(&file, false, &script.tool);  	if (session == NULL)  		return -ENOMEM; +	script.session = session; +  	if (cpu_list) {  		if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))  			return -1; @@ -1514,7 +1565,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  			return -1;  		} -		input = open(session->filename, O_RDONLY);	/* input_name */ +		input = open(file.path, O_RDONLY);	/* input_name */  		if (input < 0) {  			perror("failed to open file");  			return -1; @@ -1554,7 +1605,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  	if (err < 0)  		goto out; -	err = __cmd_script(session); +	err = __cmd_script(&script);  	perf_session__delete(session);  	cleanup_scripting();  | 
