summaryrefslogtreecommitdiff
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 11:06:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 11:06:34 -0700
commit486adcea4a63bec206cba6f0d7f301fb945ae9d3 (patch)
tree1cdf7fed3628390186b5493087612f3681e9e912 /tools/perf/util/scripting-engines/trace-event-python.c
parent701f3b314905ac05f09fc052c87b022825d831f2 (diff)
parent1159e09476536250c2a0173d4298d15114df7a89 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "The main kernel side changes were: - Modernize the kprobe and uprobe creation/destruction tooling ABIs: The existing text based APIs (kprobe_events and uprobe_events in tracefs), are naive, limited ABIs in that they require user-space to clean up after themselves, which is both difficult and fragile if the tool is buggy or exits unexpectedly. In other words they are not really suited for modern, robust tooling. So introduce a modern, file descriptor based ABI that does not have these limitations: introduce the 'perf_kprobe' and 'perf_uprobe' PMUs and extend the perf_event_open() syscall to create events with a kprobe/uprobe attached to them. These [k,u]probe are associated with this file descriptor, so they are not available in tracefs. (Song Liu) - Intel Cannon Lake CPU support (Harry Pan) - Intel PT cleanups (Alexander Shishkin) - Improve the performance of pinned/flexible event groups by using RB trees (Alexey Budankov) - Add PERF_EVENT_IOC_MODIFY_ATTRIBUTES which allows the modification of hardware breakpoints, which new ABI variant massively speeds up existing tooling that uses hardware breakpoints to instrument (and debug) memory usage. (Milind Chabbi, Jiri Olsa) - Various Intel PEBS handling fixes and improvements, and other Intel PMU improvements (Kan Liang) - Various perf core improvements and optimizations (Peter Zijlstra) - ... misc cleanups, fixes and updates. There's over 200 tooling commits, here's an (imperfect) list of highlights: - 'perf annotate' improvements: * Recognize and handle jumps to other functions as calls, which improves the navigation along jumps and back. (Arnaldo Carvalho de Melo) * Add the 'P' hotkey in TUI annotation to dump annotation output into a file, to ease e-mail reporting of annotation details. (Arnaldo Carvalho de Melo) * Add an IPC/cycles column to the TUI (Jin Yao) * Improve s390 assembly annotation (Thomas Richter) * Refactor the output formatting logic to better separate it into interactive and non-interactive features and add the --stdio2 output variant to demonstrate this. (Arnaldo Carvalho de Melo) - 'perf script' improvements: * Add Python 3 support (Jaroslav Škarvada) * Add --show-round-event (Jiri Olsa) - 'perf c2c' improvements: * Add NUMA analysis support (Jiri Olsa) - 'perf trace' improvements: * Improve PowerPC support (Ravi Bangoria) - 'perf inject' improvements: * Integrate ARM CoreSight traces (Robert Walker) - 'perf stat' improvements: * Add the --interval-count option (yuzhoujian) * Add the --timeout option (yuzhoujian) - 'perf sched' improvements (Changbin Du) - Vendor events improvements : * Add IBM s390 vendor events (Thomas Richter) * Add and improve arm64 vendor events (John Garry, Ganapatrao Kulkarni) * Update POWER9 vendor events (Sukadev Bhattiprolu) - Intel PT tooling improvements (Adrian Hunter) - PMU handling improvements (Agustin Vega-Frias) - Record machine topology in perf.data (Jiri Olsa) - Various overwrite related cleanups (Kan Liang) - Add arm64 dwarf post unwind support (Kim Phillips, Jean Pihet) - ... and lots of other changes, cleanups and fixes, see the shortlog and Git history for details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (262 commits) perf/x86/intel: Enable C-state residency events for Cannon Lake perf/x86/intel: Add Cannon Lake support for RAPL profiling perf/x86/pt, coresight: Clean up address filter structure perf vendor events s390: Add JSON files for IBM z14 perf vendor events s390: Add JSON files for IBM z13 perf vendor events s390: Add JSON files for IBM zEC12 zBC12 perf vendor events s390: Add JSON files for IBM z196 perf vendor events s390: Add JSON files for IBM z10EC z10BC perf mmap: Be consistent when checking for an unmaped ring buffer perf mmap: Fix accessing unmapped mmap in perf_mmap__read_done() perf build: Fix check-headers.sh opts assignment perf/x86: Update rdpmc_always_available static key to the modern API perf annotate: Use absolute addresses to calculate jump target offsets perf annotate: Defer searching for comma in raw line till it is needed perf annotate: Support jumping from one function to another perf annotate: Add "_local" to jump/offset validation routines perf python: Reference Py_None before returning it perf annotate: Mark jumps to outher functions with the call arrow perf annotate: Pass function descriptor to its instruction parsing routines perf annotate: No need to calculate notes->start twice ...
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c147
1 files changed, 104 insertions, 43 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index ea070883c593..10dd5fce082b 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -49,7 +49,37 @@
#include "print_binary.h"
#include "stat.h"
+#if PY_MAJOR_VERSION < 3
+#define _PyUnicode_FromString(arg) \
+ PyString_FromString(arg)
+#define _PyUnicode_FromStringAndSize(arg1, arg2) \
+ PyString_FromStringAndSize((arg1), (arg2))
+#define _PyBytes_FromStringAndSize(arg1, arg2) \
+ PyString_FromStringAndSize((arg1), (arg2))
+#define _PyLong_FromLong(arg) \
+ PyInt_FromLong(arg)
+#define _PyLong_AsLong(arg) \
+ PyInt_AsLong(arg)
+#define _PyCapsule_New(arg1, arg2, arg3) \
+ PyCObject_FromVoidPtr((arg1), (arg2))
+
PyMODINIT_FUNC initperf_trace_context(void);
+#else
+#define _PyUnicode_FromString(arg) \
+ PyUnicode_FromString(arg)
+#define _PyUnicode_FromStringAndSize(arg1, arg2) \
+ PyUnicode_FromStringAndSize((arg1), (arg2))
+#define _PyBytes_FromStringAndSize(arg1, arg2) \
+ PyBytes_FromStringAndSize((arg1), (arg2))
+#define _PyLong_FromLong(arg) \
+ PyLong_FromLong(arg)
+#define _PyLong_AsLong(arg) \
+ PyLong_AsLong(arg)
+#define _PyCapsule_New(arg1, arg2, arg3) \
+ PyCapsule_New((arg1), (arg2), (arg3))
+
+PyMODINIT_FUNC PyInit_perf_trace_context(void);
+#endif
#define TRACE_EVENT_TYPE_MAX \
((1 << (sizeof(unsigned short) * 8)) - 1)
@@ -135,7 +165,7 @@ static int get_argument_count(PyObject *handler)
PyObject *arg_count_obj = PyObject_GetAttrString(code_obj,
"co_argcount");
if (arg_count_obj) {
- arg_count = (int) PyInt_AsLong(arg_count_obj);
+ arg_count = (int) _PyLong_AsLong(arg_count_obj);
Py_DECREF(arg_count_obj);
}
Py_DECREF(code_obj);
@@ -182,10 +212,10 @@ static void define_value(enum print_arg_type field_type,
value = eval_flag(field_value);
- PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
- PyTuple_SetItem(t, n++, PyString_FromString(field_name));
- PyTuple_SetItem(t, n++, PyInt_FromLong(value));
- PyTuple_SetItem(t, n++, PyString_FromString(field_str));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(value));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_str));
try_call_object(handler_name, t);
@@ -223,10 +253,10 @@ static void define_field(enum print_arg_type field_type,
if (!t)
Py_FatalError("couldn't create Python tuple");
- PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
- PyTuple_SetItem(t, n++, PyString_FromString(field_name));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name));
if (field_type == PRINT_FLAGS)
- PyTuple_SetItem(t, n++, PyString_FromString(delim));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(delim));
try_call_object(handler_name, t);
@@ -325,12 +355,12 @@ static PyObject *get_field_numeric_entry(struct event_format *event,
if (field->flags & FIELD_IS_SIGNED) {
if ((long long)val >= LONG_MIN &&
(long long)val <= LONG_MAX)
- obj = PyInt_FromLong(val);
+ obj = _PyLong_FromLong(val);
else
obj = PyLong_FromLongLong(val);
} else {
if (val <= LONG_MAX)
- obj = PyInt_FromLong(val);
+ obj = _PyLong_FromLong(val);
else
obj = PyLong_FromUnsignedLongLong(val);
}
@@ -389,9 +419,9 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
pydict_set_item_string_decref(pysym, "end",
PyLong_FromUnsignedLongLong(node->sym->end));
pydict_set_item_string_decref(pysym, "binding",
- PyInt_FromLong(node->sym->binding));
+ _PyLong_FromLong(node->sym->binding));
pydict_set_item_string_decref(pysym, "name",
- PyString_FromStringAndSize(node->sym->name,
+ _PyUnicode_FromStringAndSize(node->sym->name,
node->sym->namelen));
pydict_set_item_string_decref(pyelem, "sym", pysym);
}
@@ -406,7 +436,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
dsoname = map->dso->name;
}
pydict_set_item_string_decref(pyelem, "dso",
- PyString_FromString(dsoname));
+ _PyUnicode_FromString(dsoname));
}
callchain_cursor_advance(&callchain_cursor);
@@ -483,16 +513,16 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
if (!dict_sample)
Py_FatalError("couldn't create Python dictionary");
- pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
- pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
+ pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel)));
+ pydict_set_item_string_decref(dict, "attr", _PyUnicode_FromStringAndSize(
(const char *)&evsel->attr, sizeof(evsel->attr)));
pydict_set_item_string_decref(dict_sample, "pid",
- PyInt_FromLong(sample->pid));
+ _PyLong_FromLong(sample->pid));
pydict_set_item_string_decref(dict_sample, "tid",
- PyInt_FromLong(sample->tid));
+ _PyLong_FromLong(sample->tid));
pydict_set_item_string_decref(dict_sample, "cpu",
- PyInt_FromLong(sample->cpu));
+ _PyLong_FromLong(sample->cpu));
pydict_set_item_string_decref(dict_sample, "ip",
PyLong_FromUnsignedLongLong(sample->ip));
pydict_set_item_string_decref(dict_sample, "time",
@@ -504,17 +534,17 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
set_sample_read_in_dict(dict_sample, sample, evsel);
pydict_set_item_string_decref(dict, "sample", dict_sample);
- pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
+ pydict_set_item_string_decref(dict, "raw_buf", _PyBytes_FromStringAndSize(
(const char *)sample->raw_data, sample->raw_size));
pydict_set_item_string_decref(dict, "comm",
- PyString_FromString(thread__comm_str(al->thread)));
+ _PyUnicode_FromString(thread__comm_str(al->thread)));
if (al->map) {
pydict_set_item_string_decref(dict, "dso",
- PyString_FromString(al->map->dso->name));
+ _PyUnicode_FromString(al->map->dso->name));
}
if (al->sym) {
pydict_set_item_string_decref(dict, "symbol",
- PyString_FromString(al->sym->name));
+ _PyUnicode_FromString(al->sym->name));
}
pydict_set_item_string_decref(dict, "callchain", callchain);
@@ -574,9 +604,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
scripting_context->event_data = data;
scripting_context->pevent = evsel->tp_format->pevent;
- context = PyCObject_FromVoidPtr(scripting_context, NULL);
+ context = _PyCapsule_New(scripting_context, NULL, NULL);
- PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(handler_name));
PyTuple_SetItem(t, n++, context);
/* ip unwinding */
@@ -585,18 +615,18 @@ static void python_process_tracepoint(struct perf_sample *sample,
Py_INCREF(callchain);
if (!dict) {
- PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
- PyTuple_SetItem(t, n++, PyInt_FromLong(s));
- PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
- PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
- PyTuple_SetItem(t, n++, PyString_FromString(comm));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(s));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(ns));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(pid));
+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(comm));
PyTuple_SetItem(t, n++, callchain);
} else {
- pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
- pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
- pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
- pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
- pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
+ pydict_set_item_string_decref(dict, "common_cpu", _PyLong_FromLong(cpu));
+ pydict_set_item_string_decref(dict, "common_s", _PyLong_FromLong(s));
+ pydict_set_item_string_decref(dict, "common_ns", _PyLong_FromLong(ns));
+ pydict_set_item_string_decref(dict, "common_pid", _PyLong_FromLong(pid));
+ pydict_set_item_string_decref(dict, "common_comm", _PyUnicode_FromString(comm));
pydict_set_item_string_decref(dict, "common_callchain", callchain);
}
for (field = event->format.fields; field; field = field->next) {
@@ -615,7 +645,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
}
if (field->flags & FIELD_IS_STRING &&
is_printable_array(data + offset, len)) {
- obj = PyString_FromString((char *) data + offset);
+ obj = _PyUnicode_FromString((char *) data + offset);
} else {
obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
field->flags &= ~FIELD_IS_STRING;
@@ -668,7 +698,7 @@ static PyObject *tuple_new(unsigned int sz)
static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
{
#if BITS_PER_LONG == 64
- return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
#endif
#if BITS_PER_LONG == 32
return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val));
@@ -677,12 +707,12 @@ static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
{
- return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
}
static int tuple_set_string(PyObject *t, unsigned int pos, const char *s)
{
- return PyTuple_SetItem(t, pos, PyString_FromString(s));
+ return PyTuple_SetItem(t, pos, _PyUnicode_FromString(s));
}
static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel)
@@ -1029,8 +1059,8 @@ process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp,
return;
}
- PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
- PyTuple_SetItem(t, n++, PyInt_FromLong(thread));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu));
+ PyTuple_SetItem(t, n++, _PyLong_FromLong(thread));
tuple_set_u64(t, n++, tstamp);
tuple_set_u64(t, n++, count->val);
@@ -1212,27 +1242,58 @@ static void set_table_handlers(struct tables *tables)
SET_TABLE_HANDLER(call_return);
}
+#if PY_MAJOR_VERSION < 3
+static void _free_command_line(const char **command_line, int num)
+{
+ free(command_line);
+}
+#else
+static void _free_command_line(wchar_t **command_line, int num)
+{
+ int i;
+ for (i = 0; i < num; i++)
+ PyMem_RawFree(command_line[i]);
+ free(command_line);
+}
+#endif
+
+
/*
* Start trace script
*/
static int python_start_script(const char *script, int argc, const char **argv)
{
struct tables *tables = &tables_global;
+#if PY_MAJOR_VERSION < 3
const char **command_line;
+#else
+ wchar_t **command_line;
+#endif
char buf[PATH_MAX];
int i, err = 0;
FILE *fp;
+#if PY_MAJOR_VERSION < 3
command_line = malloc((argc + 1) * sizeof(const char *));
command_line[0] = script;
for (i = 1; i < argc + 1; i++)
command_line[i] = argv[i - 1];
+#else
+ command_line = malloc((argc + 1) * sizeof(wchar_t *));
+ command_line[0] = Py_DecodeLocale(script, NULL);
+ for (i = 1; i < argc + 1; i++)
+ command_line[i] = Py_DecodeLocale(argv[i - 1], NULL);
+#endif
Py_Initialize();
+#if PY_MAJOR_VERSION < 3
initperf_trace_context();
-
PySys_SetArgv(argc + 1, (char **)command_line);
+#else
+ PyInit_perf_trace_context();
+ PySys_SetArgv(argc + 1, command_line);
+#endif
fp = fopen(script, "r");
if (!fp) {
@@ -1262,12 +1323,12 @@ static int python_start_script(const char *script, int argc, const char **argv)
goto error;
}
- free(command_line);
+ _free_command_line(command_line, argc + 1);
return err;
error:
Py_Finalize();
- free(command_line);
+ _free_command_line(command_line, argc + 1);
return err;
}