summaryrefslogtreecommitdiff
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c231
1 files changed, 44 insertions, 187 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index cbce2545da45..95d91a0b23af 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -27,13 +27,11 @@
#include <errno.h>
#include "../../perf.h"
-#include "../debug.h"
#include "../evsel.h"
#include "../util.h"
#include "../event.h"
#include "../thread.h"
#include "../trace-event.h"
-#include "../machine.h"
PyMODINIT_FUNC initperf_trace_context(void);
@@ -52,14 +50,10 @@ static int zero_flag_atom;
static PyObject *main_module, *main_dict;
-static void handler_call_die(const char *handler_name) NORETURN;
static void handler_call_die(const char *handler_name)
{
PyErr_Print();
Py_FatalError("problem in Python trace event handler");
- // Py_FatalError does not return
- // but we have to make the compiler happy
- abort();
}
/*
@@ -103,7 +97,6 @@ static void define_value(enum print_arg_type field_type,
retval = PyObject_CallObject(handler, t);
if (retval == NULL)
handler_call_die(handler_name);
- Py_DECREF(retval);
}
Py_DECREF(t);
@@ -150,7 +143,6 @@ static void define_field(enum print_arg_type field_type,
retval = PyObject_CallObject(handler, t);
if (retval == NULL)
handler_call_die(handler_name);
- Py_DECREF(retval);
}
Py_DECREF(t);
@@ -169,7 +161,8 @@ static void define_event_symbols(struct event_format *event,
zero_flag_atom = 0;
break;
case PRINT_FIELD:
- free(cur_field_name);
+ if (cur_field_name)
+ free(cur_field_name);
cur_field_name = strdup(args->field.name);
break;
case PRINT_FLAGS:
@@ -205,7 +198,6 @@ static void define_event_symbols(struct event_format *event,
case PRINT_BSTRING:
case PRINT_DYNAMIC_ARRAY:
case PRINT_FUNC:
- case PRINT_BITMASK:
/* we should warn... */
return;
}
@@ -239,133 +231,18 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
return event;
}
-static PyObject *get_field_numeric_entry(struct event_format *event,
- struct format_field *field, void *data)
-{
- bool is_array = field->flags & FIELD_IS_ARRAY;
- PyObject *obj, *list = NULL;
- unsigned long long val;
- unsigned int item_size, n_items, i;
-
- if (is_array) {
- list = PyList_New(field->arraylen);
- item_size = field->size / field->arraylen;
- n_items = field->arraylen;
- } else {
- item_size = field->size;
- n_items = 1;
- }
-
- for (i = 0; i < n_items; i++) {
-
- val = read_size(event, data + field->offset + i * item_size,
- item_size);
- if (field->flags & FIELD_IS_SIGNED) {
- if ((long long)val >= LONG_MIN &&
- (long long)val <= LONG_MAX)
- obj = PyInt_FromLong(val);
- else
- obj = PyLong_FromLongLong(val);
- } else {
- if (val <= LONG_MAX)
- obj = PyInt_FromLong(val);
- else
- obj = PyLong_FromUnsignedLongLong(val);
- }
- if (is_array)
- PyList_SET_ITEM(list, i, obj);
- }
- if (is_array)
- obj = list;
- return obj;
-}
-
-
-static PyObject *python_process_callchain(struct perf_sample *sample,
- struct perf_evsel *evsel,
- struct addr_location *al)
-{
- PyObject *pylist;
-
- pylist = PyList_New(0);
- if (!pylist)
- Py_FatalError("couldn't create Python list");
-
- if (!symbol_conf.use_callchain || !sample->callchain)
- goto exit;
-
- if (machine__resolve_callchain(al->machine, evsel, al->thread,
- sample, NULL, NULL,
- PERF_MAX_STACK_DEPTH) != 0) {
- pr_err("Failed to resolve callchain. Skipping\n");
- goto exit;
- }
- callchain_cursor_commit(&callchain_cursor);
-
-
- while (1) {
- PyObject *pyelem;
- struct callchain_cursor_node *node;
- node = callchain_cursor_current(&callchain_cursor);
- if (!node)
- break;
-
- pyelem = PyDict_New();
- if (!pyelem)
- Py_FatalError("couldn't create Python dictionary");
-
-
- pydict_set_item_string_decref(pyelem, "ip",
- PyLong_FromUnsignedLongLong(node->ip));
-
- if (node->sym) {
- PyObject *pysym = PyDict_New();
- if (!pysym)
- Py_FatalError("couldn't create Python dictionary");
- pydict_set_item_string_decref(pysym, "start",
- PyLong_FromUnsignedLongLong(node->sym->start));
- pydict_set_item_string_decref(pysym, "end",
- PyLong_FromUnsignedLongLong(node->sym->end));
- pydict_set_item_string_decref(pysym, "binding",
- PyInt_FromLong(node->sym->binding));
- pydict_set_item_string_decref(pysym, "name",
- PyString_FromStringAndSize(node->sym->name,
- node->sym->namelen));
- pydict_set_item_string_decref(pyelem, "sym", pysym);
- }
-
- if (node->map) {
- struct map *map = node->map;
- const char *dsoname = "[unknown]";
- if (map && map->dso && (map->dso->name || map->dso->long_name)) {
- if (symbol_conf.show_kernel_path && map->dso->long_name)
- dsoname = map->dso->long_name;
- else if (map->dso->name)
- dsoname = map->dso->name;
- }
- pydict_set_item_string_decref(pyelem, "dso",
- PyString_FromString(dsoname));
- }
-
- callchain_cursor_advance(&callchain_cursor);
- PyList_Append(pylist, pyelem);
- Py_DECREF(pyelem);
- }
-
-exit:
- return pylist;
-}
-
-
-static void python_process_tracepoint(struct perf_sample *sample,
- struct perf_evsel *evsel,
- struct thread *thread,
- struct addr_location *al)
+static void python_process_tracepoint(union perf_event *perf_event
+ __maybe_unused,
+ struct perf_sample *sample,
+ struct perf_evsel *evsel,
+ struct machine *machine __maybe_unused,
+ struct thread *thread,
+ struct addr_location *al)
{
- PyObject *handler, *retval, *context, *t, *obj, *callchain;
- PyObject *dict = NULL;
+ PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
static char handler_name[256];
struct format_field *field;
+ unsigned long long val;
unsigned long s, ns;
struct event_format *event;
unsigned n = 0;
@@ -373,7 +250,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- const char *comm = thread__comm_str(thread);
+ char *comm = thread->comm;
t = PyTuple_New(MAX_FIELDS);
if (!t)
@@ -406,23 +283,18 @@ static void python_process_tracepoint(struct perf_sample *sample,
PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
PyTuple_SetItem(t, n++, context);
- /* ip unwinding */
- callchain = python_process_callchain(sample, evsel, al);
-
if (handler) {
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++, 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_callchain", callchain);
}
for (field = event->format.fields; field; field = field->next) {
if (field->flags & FIELD_IS_STRING) {
@@ -434,7 +306,20 @@ static void python_process_tracepoint(struct perf_sample *sample,
offset = field->offset;
obj = PyString_FromString((char *)data + offset);
} else { /* FIELD_IS_NUMERIC */
- obj = get_field_numeric_entry(event, field, data);
+ val = read_size(event, data + field->offset,
+ field->size);
+ if (field->flags & FIELD_IS_SIGNED) {
+ if ((long long)val >= LONG_MIN &&
+ (long long)val <= LONG_MAX)
+ obj = PyInt_FromLong(val);
+ else
+ obj = PyLong_FromLongLong(val);
+ } else {
+ if (val <= LONG_MAX)
+ obj = PyInt_FromLong(val);
+ else
+ obj = PyLong_FromUnsignedLongLong(val);
+ }
}
if (handler)
PyTuple_SetItem(t, n++, obj);
@@ -442,7 +327,6 @@ static void python_process_tracepoint(struct perf_sample *sample,
pydict_set_item_string_decref(dict, field->name, obj);
}
-
if (!handler)
PyTuple_SetItem(t, n++, dict);
@@ -453,7 +337,6 @@ static void python_process_tracepoint(struct perf_sample *sample,
retval = PyObject_CallObject(handler, t);
if (retval == NULL)
handler_call_die(handler_name);
- Py_DECREF(retval);
} else {
handler = PyDict_GetItemString(main_dict, "trace_unhandled");
if (handler && PyCallable_Check(handler)) {
@@ -461,7 +344,6 @@ static void python_process_tracepoint(struct perf_sample *sample,
retval = PyObject_CallObject(handler, t);
if (retval == NULL)
handler_call_die("trace_unhandled");
- Py_DECREF(retval);
}
Py_DECREF(dict);
}
@@ -469,12 +351,15 @@ static void python_process_tracepoint(struct perf_sample *sample,
Py_DECREF(t);
}
-static void python_process_general_event(struct perf_sample *sample,
+static void python_process_general_event(union perf_event *perf_event
+ __maybe_unused,
+ struct perf_sample *sample,
struct perf_evsel *evsel,
+ struct machine *machine __maybe_unused,
struct thread *thread,
struct addr_location *al)
{
- PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample;
+ PyObject *handler, *retval, *t, *dict;
static char handler_name[64];
unsigned n = 0;
@@ -490,10 +375,6 @@ static void python_process_general_event(struct perf_sample *sample,
if (!dict)
Py_FatalError("couldn't create Python dictionary");
- dict_sample = PyDict_New();
- if (!dict_sample)
- Py_FatalError("couldn't create Python dictionary");
-
snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
handler = PyDict_GetItemString(main_dict, handler_name);
@@ -503,25 +384,12 @@ static void python_process_general_event(struct perf_sample *sample,
pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
(const char *)&evsel->attr, sizeof(evsel->attr)));
-
- pydict_set_item_string_decref(dict_sample, "pid",
- PyInt_FromLong(sample->pid));
- pydict_set_item_string_decref(dict_sample, "tid",
- PyInt_FromLong(sample->tid));
- pydict_set_item_string_decref(dict_sample, "cpu",
- PyInt_FromLong(sample->cpu));
- pydict_set_item_string_decref(dict_sample, "ip",
- PyLong_FromUnsignedLongLong(sample->ip));
- pydict_set_item_string_decref(dict_sample, "time",
- PyLong_FromUnsignedLongLong(sample->time));
- pydict_set_item_string_decref(dict_sample, "period",
- PyLong_FromUnsignedLongLong(sample->period));
- pydict_set_item_string_decref(dict, "sample", dict_sample);
-
+ pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize(
+ (const char *)sample, sizeof(*sample)));
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
(const char *)sample->raw_data, sample->raw_size));
pydict_set_item_string_decref(dict, "comm",
- PyString_FromString(thread__comm_str(thread)));
+ PyString_FromString(thread->comm));
if (al->map) {
pydict_set_item_string_decref(dict, "dso",
PyString_FromString(al->map->dso->name));
@@ -531,10 +399,6 @@ static void python_process_general_event(struct perf_sample *sample,
PyString_FromString(al->sym->name));
}
- /* ip unwinding */
- callchain = python_process_callchain(sample, evsel, al);
- pydict_set_item_string_decref(dict, "callchain", callchain);
-
PyTuple_SetItem(t, n++, dict);
if (_PyTuple_Resize(&t, n) == -1)
Py_FatalError("error resizing Python tuple");
@@ -542,25 +406,27 @@ static void python_process_general_event(struct perf_sample *sample,
retval = PyObject_CallObject(handler, t);
if (retval == NULL)
handler_call_die(handler_name);
- Py_DECREF(retval);
exit:
Py_DECREF(dict);
Py_DECREF(t);
}
-static void python_process_event(union perf_event *event __maybe_unused,
+static void python_process_event(union perf_event *perf_event,
struct perf_sample *sample,
struct perf_evsel *evsel,
+ struct machine *machine,
struct thread *thread,
struct addr_location *al)
{
switch (evsel->attr.type) {
case PERF_TYPE_TRACEPOINT:
- python_process_tracepoint(sample, evsel, thread, al);
+ python_process_tracepoint(perf_event, sample, evsel,
+ machine, thread, al);
break;
/* Reserve for future process_hw/sw/raw APIs */
default:
- python_process_general_event(sample, evsel, thread, al);
+ python_process_general_event(perf_event, sample, evsel,
+ machine, thread, al);
}
}
@@ -664,7 +530,8 @@ static int python_stop_script(void)
retval = PyObject_CallObject(handler, NULL);
if (retval == NULL)
handler_call_die("trace_end");
- Py_DECREF(retval);
+ else
+ Py_DECREF(retval);
out:
Py_XDECREF(main_dict);
Py_XDECREF(main_module);
@@ -731,7 +598,6 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
fprintf(ofp, "common_nsecs, ");
fprintf(ofp, "common_pid, ");
fprintf(ofp, "common_comm,\n\t");
- fprintf(ofp, "common_callchain, ");
not_first = 0;
count = 0;
@@ -766,7 +632,6 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
fprintf(ofp, "%s=", f->name);
if (f->flags & FIELD_IS_STRING ||
f->flags & FIELD_IS_FLAG ||
- f->flags & FIELD_IS_ARRAY ||
f->flags & FIELD_IS_SYMBOLIC)
fprintf(ofp, "%%s");
else if (f->flags & FIELD_IS_SIGNED)
@@ -775,7 +640,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
fprintf(ofp, "%%u");
}
- fprintf(ofp, "\" %% \\\n\t\t(");
+ fprintf(ofp, "\\n\" %% \\\n\t\t(");
not_first = 0;
count = 0;
@@ -811,15 +676,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
fprintf(ofp, "%s", f->name);
}
- fprintf(ofp, ")\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\telse:");
- fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
- fprintf(ofp, "\t\tprint \"\\n\"\n\n");
-
+ fprintf(ofp, "),\n\n");
}
fprintf(ofp, "def trace_unhandled(event_name, context, "