aboutsummaryrefslogtreecommitdiffstats
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.c50
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 */
64static 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
59static void define_value(enum print_arg_type field_type, 70static 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