diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
| -rw-r--r-- | tools/perf/builtin-script.c | 74 | 
1 files changed, 53 insertions, 21 deletions
| diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f57035b89c15..b9b9e58a6c39 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -184,10 +184,6 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,  		if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",  					    PERF_OUTPUT_IP))  			return -EINVAL; - -		if (!no_callchain && -		    !(attr->sample_type & PERF_SAMPLE_CALLCHAIN)) -			symbol_conf.use_callchain = false;  	}  	if (PRINT_FIELD(ADDR) && @@ -290,6 +286,19 @@ static int perf_session__check_output_opt(struct perf_session *session)  		set_print_ip_opts(&evsel->attr);  	} +	if (!no_callchain) { +		bool use_callchain = false; + +		evlist__for_each(session->evlist, evsel) { +			if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { +				use_callchain = true; +				break; +			} +		} +		if (!use_callchain) +			symbol_conf.use_callchain = false; +	} +  	/*  	 * set default for tracepoints to print symbols only  	 * if callchains are present @@ -476,6 +485,11 @@ static int default_start_script(const char *script __maybe_unused,  	return 0;  } +static int default_flush_script(void) +{ +	return 0; +} +  static int default_stop_script(void)  {  	return 0; @@ -489,6 +503,7 @@ static int default_generate_script(struct pevent *pevent __maybe_unused,  static struct scripting_ops default_scripting_ops = {  	.start_script		= default_start_script, +	.flush_script		= default_flush_script,  	.stop_script		= default_stop_script,  	.process_event		= process_event,  	.generate_script	= default_generate_script, @@ -504,6 +519,11 @@ static void setup_scripting(void)  	scripting_ops = &default_scripting_ops;  } +static int flush_scripting(void) +{ +	return scripting_ops->flush_script(); +} +  static int cleanup_scripting(void)  {  	pr_debug("\nperf script stopped\n"); @@ -1471,12 +1491,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  	bool show_full_info = false;  	bool header = false;  	bool header_only = false; +	bool script_started = false;  	char *rec_script_path = NULL;  	char *rep_script_path = NULL;  	struct perf_session *session;  	char *script_path = NULL;  	const char **__argv; -	int i, j, err; +	int i, j, err = 0;  	struct perf_script script = {  		.tool = {  			.sample		 = process_sample_event, @@ -1488,7 +1509,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  			.attr		 = process_attr,  			.tracing_data	 = perf_event__process_tracing_data,  			.build_id	 = perf_event__process_build_id, -			.ordered_samples = true, +			.ordered_events	 = true,  			.ordering_requires_timestamps = true,  		},  	}; @@ -1718,26 +1739,28 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  		exit(-1);  	} -	if (symbol__init() < 0) -		return -1;  	if (!script_name)  		setup_pager();  	session = perf_session__new(&file, false, &script.tool);  	if (session == NULL) -		return -ENOMEM; +		return -1;  	if (header || header_only) {  		perf_session__fprintf_info(session, stdout, show_full_info);  		if (header_only) -			return 0; +			goto out_delete;  	} +	if (symbol__init(&session->header.env) < 0) +		goto out_delete; +  	script.session = session;  	if (cpu_list) { -		if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) -			return -1; +		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); +		if (err < 0) +			goto out_delete;  	}  	if (!no_callchain) @@ -1752,53 +1775,62 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)  		if (output_set_by_user()) {  			fprintf(stderr,  				"custom fields not supported for generated scripts"); -			return -1; +			err = -EINVAL; +			goto out_delete;  		}  		input = open(file.path, O_RDONLY);	/* input_name */  		if (input < 0) { +			err = -errno;  			perror("failed to open file"); -			return -1; +			goto out_delete;  		}  		err = fstat(input, &perf_stat);  		if (err < 0) {  			perror("failed to stat file"); -			return -1; +			goto out_delete;  		}  		if (!perf_stat.st_size) {  			fprintf(stderr, "zero-sized file, nothing to do!\n"); -			return 0; +			goto out_delete;  		}  		scripting_ops = script_spec__lookup(generate_script_lang);  		if (!scripting_ops) {  			fprintf(stderr, "invalid language specifier"); -			return -1; +			err = -ENOENT; +			goto out_delete;  		}  		err = scripting_ops->generate_script(session->tevent.pevent,  						     "perf-script"); -		goto out; +		goto out_delete;  	}  	if (script_name) {  		err = scripting_ops->start_script(script_name, argc, argv);  		if (err) -			goto out; +			goto out_delete;  		pr_debug("perf script started with script %s\n\n", script_name); +		script_started = true;  	}  	err = perf_session__check_output_opt(session);  	if (err < 0) -		goto out; +		goto out_delete;  	err = __cmd_script(&script); +	flush_scripting(); + +out_delete:  	perf_session__delete(session); -	cleanup_scripting(); + +	if (script_started) +		cleanup_scripting();  out:  	return err;  } | 
