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 | 231 |
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, " |