diff options
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 289 | 
1 files changed, 260 insertions, 29 deletions
| diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 10dd5fce082b..bc32e57d17be 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -48,6 +48,7 @@  #include "cpumap.h"  #include "print_binary.h"  #include "stat.h" +#include "mem-events.h"  #if PY_MAJOR_VERSION < 3  #define _PyUnicode_FromString(arg) \ @@ -372,6 +373,19 @@ static PyObject *get_field_numeric_entry(struct event_format *event,  	return obj;  } +static const char *get_dsoname(struct map *map) +{ +	const char *dsoname = "[unknown]"; + +	if (map && map->dso) { +		if (symbol_conf.show_kernel_path && map->dso->long_name) +			dsoname = map->dso->long_name; +		else +			dsoname = map->dso->name; +	} + +	return dsoname; +}  static PyObject *python_process_callchain(struct perf_sample *sample,  					 struct perf_evsel *evsel, @@ -427,14 +441,8 @@ static PyObject *python_process_callchain(struct perf_sample *sample,  		}  		if (node->map) { -			struct map *map = node->map; -			const char *dsoname = "[unknown]"; -			if (map && map->dso) { -				if (symbol_conf.show_kernel_path && map->dso->long_name) -					dsoname = map->dso->long_name; -				else -					dsoname = map->dso->name; -			} +			const char *dsoname = get_dsoname(node->map); +  			pydict_set_item_string_decref(pyelem, "dso",  					_PyUnicode_FromString(dsoname));  		} @@ -448,6 +456,166 @@ exit:  	return pylist;  } +static PyObject *python_process_brstack(struct perf_sample *sample, +					struct thread *thread) +{ +	struct branch_stack *br = sample->branch_stack; +	PyObject *pylist; +	u64 i; + +	pylist = PyList_New(0); +	if (!pylist) +		Py_FatalError("couldn't create Python list"); + +	if (!(br && br->nr)) +		goto exit; + +	for (i = 0; i < br->nr; i++) { +		PyObject *pyelem; +		struct addr_location al; +		const char *dsoname; + +		pyelem = PyDict_New(); +		if (!pyelem) +			Py_FatalError("couldn't create Python dictionary"); + +		pydict_set_item_string_decref(pyelem, "from", +		    PyLong_FromUnsignedLongLong(br->entries[i].from)); +		pydict_set_item_string_decref(pyelem, "to", +		    PyLong_FromUnsignedLongLong(br->entries[i].to)); +		pydict_set_item_string_decref(pyelem, "mispred", +		    PyBool_FromLong(br->entries[i].flags.mispred)); +		pydict_set_item_string_decref(pyelem, "predicted", +		    PyBool_FromLong(br->entries[i].flags.predicted)); +		pydict_set_item_string_decref(pyelem, "in_tx", +		    PyBool_FromLong(br->entries[i].flags.in_tx)); +		pydict_set_item_string_decref(pyelem, "abort", +		    PyBool_FromLong(br->entries[i].flags.abort)); +		pydict_set_item_string_decref(pyelem, "cycles", +		    PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles)); + +		thread__find_map(thread, sample->cpumode, +				 br->entries[i].from, &al); +		dsoname = get_dsoname(al.map); +		pydict_set_item_string_decref(pyelem, "from_dsoname", +					      _PyUnicode_FromString(dsoname)); + +		thread__find_map(thread, sample->cpumode, +				 br->entries[i].to, &al); +		dsoname = get_dsoname(al.map); +		pydict_set_item_string_decref(pyelem, "to_dsoname", +					      _PyUnicode_FromString(dsoname)); + +		PyList_Append(pylist, pyelem); +		Py_DECREF(pyelem); +	} + +exit: +	return pylist; +} + +static unsigned long get_offset(struct symbol *sym, struct addr_location *al) +{ +	unsigned long offset; + +	if (al->addr < sym->end) +		offset = al->addr - sym->start; +	else +		offset = al->addr - al->map->start - sym->start; + +	return offset; +} + +static int get_symoff(struct symbol *sym, struct addr_location *al, +		      bool print_off, char *bf, int size) +{ +	unsigned long offset; + +	if (!sym || !sym->name[0]) +		return scnprintf(bf, size, "%s", "[unknown]"); + +	if (!print_off) +		return scnprintf(bf, size, "%s", sym->name); + +	offset = get_offset(sym, al); + +	return scnprintf(bf, size, "%s+0x%x", sym->name, offset); +} + +static int get_br_mspred(struct branch_flags *flags, char *bf, int size) +{ +	if (!flags->mispred  && !flags->predicted) +		return scnprintf(bf, size, "%s", "-"); + +	if (flags->mispred) +		return scnprintf(bf, size, "%s", "M"); + +	return scnprintf(bf, size, "%s", "P"); +} + +static PyObject *python_process_brstacksym(struct perf_sample *sample, +					   struct thread *thread) +{ +	struct branch_stack *br = sample->branch_stack; +	PyObject *pylist; +	u64 i; +	char bf[512]; +	struct addr_location al; + +	pylist = PyList_New(0); +	if (!pylist) +		Py_FatalError("couldn't create Python list"); + +	if (!(br && br->nr)) +		goto exit; + +	for (i = 0; i < br->nr; i++) { +		PyObject *pyelem; + +		pyelem = PyDict_New(); +		if (!pyelem) +			Py_FatalError("couldn't create Python dictionary"); + +		thread__find_symbol(thread, sample->cpumode, +				    br->entries[i].from, &al); +		get_symoff(al.sym, &al, true, bf, sizeof(bf)); +		pydict_set_item_string_decref(pyelem, "from", +					      _PyUnicode_FromString(bf)); + +		thread__find_symbol(thread, sample->cpumode, +				    br->entries[i].to, &al); +		get_symoff(al.sym, &al, true, bf, sizeof(bf)); +		pydict_set_item_string_decref(pyelem, "to", +					      _PyUnicode_FromString(bf)); + +		get_br_mspred(&br->entries[i].flags, bf, sizeof(bf)); +		pydict_set_item_string_decref(pyelem, "pred", +					      _PyUnicode_FromString(bf)); + +		if (br->entries[i].flags.in_tx) { +			pydict_set_item_string_decref(pyelem, "in_tx", +					      _PyUnicode_FromString("X")); +		} else { +			pydict_set_item_string_decref(pyelem, "in_tx", +					      _PyUnicode_FromString("-")); +		} + +		if (br->entries[i].flags.abort) { +			pydict_set_item_string_decref(pyelem, "abort", +					      _PyUnicode_FromString("A")); +		} else { +			pydict_set_item_string_decref(pyelem, "abort", +					      _PyUnicode_FromString("-")); +		} + +		PyList_Append(pylist, pyelem); +		Py_DECREF(pyelem); +	} + +exit: +	return pylist; +} +  static PyObject *get_sample_value_as_tuple(struct sample_read_value *value)  {  	PyObject *t; @@ -498,12 +666,63 @@ static void set_sample_read_in_dict(PyObject *dict_sample,  	pydict_set_item_string_decref(dict_sample, "values", values);  } +static void set_sample_datasrc_in_dict(PyObject *dict, +				       struct perf_sample *sample) +{ +	struct mem_info mi = { .data_src.val = sample->data_src }; +	char decode[100]; + +	pydict_set_item_string_decref(dict, "datasrc", +			PyLong_FromUnsignedLongLong(sample->data_src)); + +	perf_script__meminfo_scnprintf(decode, 100, &mi); + +	pydict_set_item_string_decref(dict, "datasrc_decode", +			_PyUnicode_FromString(decode)); +} + +static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) +{ +	unsigned int i = 0, r; +	int printed = 0; + +	bf[0] = 0; + +	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { +		u64 val = regs->regs[i++]; + +		printed += scnprintf(bf + printed, size - printed, +				     "%5s:0x%" PRIx64 " ", +				     perf_reg_name(r), val); +	} + +	return printed; +} + +static void set_regs_in_dict(PyObject *dict, +			     struct perf_sample *sample, +			     struct perf_evsel *evsel) +{ +	struct perf_event_attr *attr = &evsel->attr; +	char bf[512]; + +	regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); + +	pydict_set_item_string_decref(dict, "iregs", +			_PyUnicode_FromString(bf)); + +	regs_map(&sample->user_regs, attr->sample_regs_user, bf, sizeof(bf)); + +	pydict_set_item_string_decref(dict, "uregs", +			_PyUnicode_FromString(bf)); +} +  static PyObject *get_perf_sample_dict(struct perf_sample *sample,  					 struct perf_evsel *evsel,  					 struct addr_location *al,  					 PyObject *callchain)  { -	PyObject *dict, *dict_sample; +	PyObject *dict, *dict_sample, *brstack, *brstacksym;  	dict = PyDict_New();  	if (!dict) @@ -531,7 +750,14 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,  			PyLong_FromUnsignedLongLong(sample->period));  	pydict_set_item_string_decref(dict_sample, "phys_addr",  			PyLong_FromUnsignedLongLong(sample->phys_addr)); +	pydict_set_item_string_decref(dict_sample, "addr", +			PyLong_FromUnsignedLongLong(sample->addr));  	set_sample_read_in_dict(dict_sample, sample, evsel); +	pydict_set_item_string_decref(dict_sample, "weight", +			PyLong_FromUnsignedLongLong(sample->weight)); +	pydict_set_item_string_decref(dict_sample, "transaction", +			PyLong_FromUnsignedLongLong(sample->transaction)); +	set_sample_datasrc_in_dict(dict_sample, sample);  	pydict_set_item_string_decref(dict, "sample", dict_sample);  	pydict_set_item_string_decref(dict, "raw_buf", _PyBytes_FromStringAndSize( @@ -549,6 +775,14 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,  	pydict_set_item_string_decref(dict, "callchain", callchain); +	brstack = python_process_brstack(sample, al->thread); +	pydict_set_item_string_decref(dict, "brstack", brstack); + +	brstacksym = python_process_brstacksym(sample, al->thread); +	pydict_set_item_string_decref(dict, "brstacksym", brstacksym); + +	set_regs_in_dict(dict, sample, evsel); +  	return dict;  } @@ -674,14 +908,11 @@ static void python_process_tracepoint(struct perf_sample *sample,  	if (_PyTuple_Resize(&t, n) == -1)  		Py_FatalError("error resizing Python tuple"); -	if (!dict) { +	if (!dict)  		call_object(handler, t, handler_name); -	} else { +	else  		call_object(handler, t, default_handler_name); -		Py_DECREF(dict); -	} -	Py_XDECREF(all_entries_dict);  	Py_DECREF(t);  } @@ -1001,7 +1232,6 @@ static void python_process_general_event(struct perf_sample *sample,  	call_object(handler, t, handler_name); -	Py_DECREF(dict);  	Py_DECREF(t);  } @@ -1393,6 +1623,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)  	fprintf(ofp, "# See the perf-script-python Documentation for the list "  		"of available functions.\n\n"); +	fprintf(ofp, "from __future__ import print_function\n\n");  	fprintf(ofp, "import os\n");  	fprintf(ofp, "import sys\n\n"); @@ -1402,10 +1633,10 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)  	fprintf(ofp, "from Core import *\n\n\n");  	fprintf(ofp, "def trace_begin():\n"); -	fprintf(ofp, "\tprint \"in trace_begin\"\n\n"); +	fprintf(ofp, "\tprint(\"in trace_begin\")\n\n");  	fprintf(ofp, "def trace_end():\n"); -	fprintf(ofp, "\tprint \"in trace_end\"\n\n"); +	fprintf(ofp, "\tprint(\"in trace_end\")\n\n");  	while ((event = trace_find_next_event(pevent, event))) {  		fprintf(ofp, "def %s__%s(", event->system, event->name); @@ -1441,7 +1672,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)  			"common_secs, common_nsecs,\n\t\t\t"  			"common_pid, common_comm)\n\n"); -		fprintf(ofp, "\t\tprint \""); +		fprintf(ofp, "\t\tprint(\"");  		not_first = 0;  		count = 0; @@ -1502,31 +1733,31 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)  				fprintf(ofp, "%s", f->name);  		} -		fprintf(ofp, ")\n\n"); +		fprintf(ofp, "))\n\n"); -		fprintf(ofp, "\t\tprint 'Sample: {'+" -			"get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); +		fprintf(ofp, "\t\tprint('Sample: {'+" +			"get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')\n\n");  		fprintf(ofp, "\t\tfor node in common_callchain:");  		fprintf(ofp, "\n\t\t\tif 'sym' in node:"); -		fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])"); +		fprintf(ofp, "\n\t\t\t\tprint(\"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name']))");  		fprintf(ofp, "\n\t\t\telse:"); -		fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n"); -		fprintf(ofp, "\t\tprint \"\\n\"\n\n"); +		fprintf(ofp, "\n\t\t\t\tprint(\"\t[%%x]\" %% (node['ip']))\n\n"); +		fprintf(ofp, "\t\tprint()\n\n");  	}  	fprintf(ofp, "def trace_unhandled(event_name, context, "  		"event_fields_dict, perf_sample_dict):\n"); -	fprintf(ofp, "\t\tprint get_dict_as_string(event_fields_dict)\n"); -	fprintf(ofp, "\t\tprint 'Sample: {'+" -		"get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); +	fprintf(ofp, "\t\tprint(get_dict_as_string(event_fields_dict))\n"); +	fprintf(ofp, "\t\tprint('Sample: {'+" +		"get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')\n\n");  	fprintf(ofp, "def print_header("  		"event_name, cpu, secs, nsecs, pid, comm):\n" -		"\tprint \"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" -		"(event_name, cpu, secs, nsecs, pid, comm),\n\n"); +		"\tprint(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" +		"(event_name, cpu, secs, nsecs, pid, comm), end=\"\")\n\n");  	fprintf(ofp, "def get_dict_as_string(a_dict, delimiter=' '):\n"  		"\treturn delimiter.join" | 
