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 | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index e87aa5d9696b..53c20e7fd900 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -56,6 +56,17 @@ static void handler_call_die(const char *handler_name) | |||
56 | Py_FatalError("problem in Python trace event handler"); | 56 | Py_FatalError("problem in Python trace event handler"); |
57 | } | 57 | } |
58 | 58 | ||
59 | /* | ||
60 | * Insert val into into the dictionary and decrement the reference counter. | ||
61 | * This is necessary for dictionaries since PyDict_SetItemString() does not | ||
62 | * steal a reference, as opposed to PyTuple_SetItem(). | ||
63 | */ | ||
64 | static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val) | ||
65 | { | ||
66 | PyDict_SetItemString(dict, key, val); | ||
67 | Py_DECREF(val); | ||
68 | } | ||
69 | |||
59 | static void define_value(enum print_arg_type field_type, | 70 | static void define_value(enum print_arg_type field_type, |
60 | const char *ev_name, | 71 | const char *ev_name, |
61 | const char *field_name, | 72 | const char *field_name, |
@@ -225,6 +236,7 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
225 | struct perf_sample *sample, | 236 | struct perf_sample *sample, |
226 | struct perf_evsel *evsel, | 237 | struct perf_evsel *evsel, |
227 | struct machine *machine __maybe_unused, | 238 | struct machine *machine __maybe_unused, |
239 | struct thread *thread, | ||
228 | struct addr_location *al) | 240 | struct addr_location *al) |
229 | { | 241 | { |
230 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; | 242 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; |
@@ -238,8 +250,7 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
238 | int cpu = sample->cpu; | 250 | int cpu = sample->cpu; |
239 | void *data = sample->raw_data; | 251 | void *data = sample->raw_data; |
240 | unsigned long long nsecs = sample->time; | 252 | unsigned long long nsecs = sample->time; |
241 | struct thread *thread = al->thread; | 253 | const char *comm = thread__comm_str(thread); |
242 | char *comm = thread->comm; | ||
243 | 254 | ||
244 | t = PyTuple_New(MAX_FIELDS); | 255 | t = PyTuple_New(MAX_FIELDS); |
245 | if (!t) | 256 | if (!t) |
@@ -279,11 +290,11 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
279 | PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); | 290 | PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); |
280 | PyTuple_SetItem(t, n++, PyString_FromString(comm)); | 291 | PyTuple_SetItem(t, n++, PyString_FromString(comm)); |
281 | } else { | 292 | } else { |
282 | PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu)); | 293 | pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); |
283 | PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s)); | 294 | pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); |
284 | PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns)); | 295 | pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); |
285 | PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid)); | 296 | pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); |
286 | PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm)); | 297 | pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); |
287 | } | 298 | } |
288 | for (field = event->format.fields; field; field = field->next) { | 299 | for (field = event->format.fields; field; field = field->next) { |
289 | if (field->flags & FIELD_IS_STRING) { | 300 | if (field->flags & FIELD_IS_STRING) { |
@@ -313,7 +324,7 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
313 | if (handler) | 324 | if (handler) |
314 | PyTuple_SetItem(t, n++, obj); | 325 | PyTuple_SetItem(t, n++, obj); |
315 | else | 326 | else |
316 | PyDict_SetItemString(dict, field->name, obj); | 327 | pydict_set_item_string_decref(dict, field->name, obj); |
317 | 328 | ||
318 | } | 329 | } |
319 | if (!handler) | 330 | if (!handler) |
@@ -345,12 +356,12 @@ static void python_process_general_event(union perf_event *perf_event | |||
345 | struct perf_sample *sample, | 356 | struct perf_sample *sample, |
346 | struct perf_evsel *evsel, | 357 | struct perf_evsel *evsel, |
347 | struct machine *machine __maybe_unused, | 358 | struct machine *machine __maybe_unused, |
359 | struct thread *thread, | ||
348 | struct addr_location *al) | 360 | struct addr_location *al) |
349 | { | 361 | { |
350 | PyObject *handler, *retval, *t, *dict; | 362 | PyObject *handler, *retval, *t, *dict; |
351 | static char handler_name[64]; | 363 | static char handler_name[64]; |
352 | unsigned n = 0; | 364 | unsigned n = 0; |
353 | struct thread *thread = al->thread; | ||
354 | 365 | ||
355 | /* | 366 | /* |
356 | * Use the MAX_FIELDS to make the function expandable, though | 367 | * Use the MAX_FIELDS to make the function expandable, though |
@@ -370,21 +381,21 @@ static void python_process_general_event(union perf_event *perf_event | |||
370 | if (!handler || !PyCallable_Check(handler)) | 381 | if (!handler || !PyCallable_Check(handler)) |
371 | goto exit; | 382 | goto exit; |
372 | 383 | ||
373 | PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); | 384 | pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); |
374 | PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize( | 385 | pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( |
375 | (const char *)&evsel->attr, sizeof(evsel->attr))); | 386 | (const char *)&evsel->attr, sizeof(evsel->attr))); |
376 | PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize( | 387 | pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize( |
377 | (const char *)sample, sizeof(*sample))); | 388 | (const char *)sample, sizeof(*sample))); |
378 | PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize( | 389 | pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( |
379 | (const char *)sample->raw_data, sample->raw_size)); | 390 | (const char *)sample->raw_data, sample->raw_size)); |
380 | PyDict_SetItemString(dict, "comm", | 391 | pydict_set_item_string_decref(dict, "comm", |
381 | PyString_FromString(thread->comm)); | 392 | PyString_FromString(thread__comm_str(thread))); |
382 | if (al->map) { | 393 | if (al->map) { |
383 | PyDict_SetItemString(dict, "dso", | 394 | pydict_set_item_string_decref(dict, "dso", |
384 | PyString_FromString(al->map->dso->name)); | 395 | PyString_FromString(al->map->dso->name)); |
385 | } | 396 | } |
386 | if (al->sym) { | 397 | if (al->sym) { |
387 | PyDict_SetItemString(dict, "symbol", | 398 | pydict_set_item_string_decref(dict, "symbol", |
388 | PyString_FromString(al->sym->name)); | 399 | PyString_FromString(al->sym->name)); |
389 | } | 400 | } |
390 | 401 | ||
@@ -404,17 +415,18 @@ static void python_process_event(union perf_event *perf_event, | |||
404 | struct perf_sample *sample, | 415 | struct perf_sample *sample, |
405 | struct perf_evsel *evsel, | 416 | struct perf_evsel *evsel, |
406 | struct machine *machine, | 417 | struct machine *machine, |
418 | struct thread *thread, | ||
407 | struct addr_location *al) | 419 | struct addr_location *al) |
408 | { | 420 | { |
409 | switch (evsel->attr.type) { | 421 | switch (evsel->attr.type) { |
410 | case PERF_TYPE_TRACEPOINT: | 422 | case PERF_TYPE_TRACEPOINT: |
411 | python_process_tracepoint(perf_event, sample, evsel, | 423 | python_process_tracepoint(perf_event, sample, evsel, |
412 | machine, al); | 424 | machine, thread, al); |
413 | break; | 425 | break; |
414 | /* Reserve for future process_hw/sw/raw APIs */ | 426 | /* Reserve for future process_hw/sw/raw APIs */ |
415 | default: | 427 | default: |
416 | python_process_general_event(perf_event, sample, evsel, | 428 | python_process_general_event(perf_event, sample, evsel, |
417 | machine, al); | 429 | machine, thread, al); |
418 | } | 430 | } |
419 | } | 431 | } |
420 | 432 | ||