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.c106
1 files changed, 102 insertions, 4 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index b6c1a69f2b18..cf65404472cb 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -32,6 +32,7 @@
32#include "../event.h" 32#include "../event.h"
33#include "../thread.h" 33#include "../thread.h"
34#include "../trace-event.h" 34#include "../trace-event.h"
35#include "../machine.h"
35 36
36PyMODINIT_FUNC initperf_trace_context(void); 37PyMODINIT_FUNC initperf_trace_context(void);
37 38
@@ -278,12 +279,90 @@ static PyObject *get_field_numeric_entry(struct event_format *event,
278 return obj; 279 return obj;
279} 280}
280 281
282
283static PyObject *python_process_callchain(struct perf_sample *sample,
284 struct perf_evsel *evsel,
285 struct addr_location *al)
286{
287 PyObject *pylist;
288
289 pylist = PyList_New(0);
290 if (!pylist)
291 Py_FatalError("couldn't create Python list");
292
293 if (!symbol_conf.use_callchain || !sample->callchain)
294 goto exit;
295
296 if (machine__resolve_callchain(al->machine, evsel, al->thread,
297 sample, NULL, NULL,
298 PERF_MAX_STACK_DEPTH) != 0) {
299 pr_err("Failed to resolve callchain. Skipping\n");
300 goto exit;
301 }
302 callchain_cursor_commit(&callchain_cursor);
303
304
305 while (1) {
306 PyObject *pyelem;
307 struct callchain_cursor_node *node;
308 node = callchain_cursor_current(&callchain_cursor);
309 if (!node)
310 break;
311
312 pyelem = PyDict_New();
313 if (!pyelem)
314 Py_FatalError("couldn't create Python dictionary");
315
316
317 pydict_set_item_string_decref(pyelem, "ip",
318 PyLong_FromUnsignedLongLong(node->ip));
319
320 if (node->sym) {
321 PyObject *pysym = PyDict_New();
322 if (!pysym)
323 Py_FatalError("couldn't create Python dictionary");
324 pydict_set_item_string_decref(pysym, "start",
325 PyLong_FromUnsignedLongLong(node->sym->start));
326 pydict_set_item_string_decref(pysym, "end",
327 PyLong_FromUnsignedLongLong(node->sym->end));
328 pydict_set_item_string_decref(pysym, "binding",
329 PyInt_FromLong(node->sym->binding));
330 pydict_set_item_string_decref(pysym, "name",
331 PyString_FromStringAndSize(node->sym->name,
332 node->sym->namelen));
333 pydict_set_item_string_decref(pyelem, "sym", pysym);
334 }
335
336 if (node->map) {
337 struct map *map = node->map;
338 const char *dsoname = "[unknown]";
339 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
340 if (symbol_conf.show_kernel_path && map->dso->long_name)
341 dsoname = map->dso->long_name;
342 else if (map->dso->name)
343 dsoname = map->dso->name;
344 }
345 pydict_set_item_string_decref(pyelem, "dso",
346 PyString_FromString(dsoname));
347 }
348
349 callchain_cursor_advance(&callchain_cursor);
350 PyList_Append(pylist, pyelem);
351 Py_DECREF(pyelem);
352 }
353
354exit:
355 return pylist;
356}
357
358
281static void python_process_tracepoint(struct perf_sample *sample, 359static void python_process_tracepoint(struct perf_sample *sample,
282 struct perf_evsel *evsel, 360 struct perf_evsel *evsel,
283 struct thread *thread, 361 struct thread *thread,
284 struct addr_location *al) 362 struct addr_location *al)
285{ 363{
286 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 364 PyObject *handler, *retval, *context, *t, *obj, *callchain;
365 PyObject *dict = NULL;
287 static char handler_name[256]; 366 static char handler_name[256];
288 struct format_field *field; 367 struct format_field *field;
289 unsigned long s, ns; 368 unsigned long s, ns;
@@ -326,18 +405,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
326 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 405 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
327 PyTuple_SetItem(t, n++, context); 406 PyTuple_SetItem(t, n++, context);
328 407
408 /* ip unwinding */
409 callchain = python_process_callchain(sample, evsel, al);
410
329 if (handler) { 411 if (handler) {
330 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 412 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
331 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 413 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
332 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 414 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
333 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 415 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
334 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 416 PyTuple_SetItem(t, n++, PyString_FromString(comm));
417 PyTuple_SetItem(t, n++, callchain);
335 } else { 418 } else {
336 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 419 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
337 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 420 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
338 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 421 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
339 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 422 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
340 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); 423 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
424 pydict_set_item_string_decref(dict, "common_callchain", callchain);
341 } 425 }
342 for (field = event->format.fields; field; field = field->next) { 426 for (field = event->format.fields; field; field = field->next) {
343 if (field->flags & FIELD_IS_STRING) { 427 if (field->flags & FIELD_IS_STRING) {
@@ -357,6 +441,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
357 pydict_set_item_string_decref(dict, field->name, obj); 441 pydict_set_item_string_decref(dict, field->name, obj);
358 442
359 } 443 }
444
360 if (!handler) 445 if (!handler)
361 PyTuple_SetItem(t, n++, dict); 446 PyTuple_SetItem(t, n++, dict);
362 447
@@ -388,7 +473,7 @@ static void python_process_general_event(struct perf_sample *sample,
388 struct thread *thread, 473 struct thread *thread,
389 struct addr_location *al) 474 struct addr_location *al)
390{ 475{
391 PyObject *handler, *retval, *t, *dict; 476 PyObject *handler, *retval, *t, *dict, *callchain;
392 static char handler_name[64]; 477 static char handler_name[64];
393 unsigned n = 0; 478 unsigned n = 0;
394 479
@@ -428,6 +513,10 @@ static void python_process_general_event(struct perf_sample *sample,
428 PyString_FromString(al->sym->name)); 513 PyString_FromString(al->sym->name));
429 } 514 }
430 515
516 /* ip unwinding */
517 callchain = python_process_callchain(sample, evsel, al);
518 pydict_set_item_string_decref(dict, "callchain", callchain);
519
431 PyTuple_SetItem(t, n++, dict); 520 PyTuple_SetItem(t, n++, dict);
432 if (_PyTuple_Resize(&t, n) == -1) 521 if (_PyTuple_Resize(&t, n) == -1)
433 Py_FatalError("error resizing Python tuple"); 522 Py_FatalError("error resizing Python tuple");
@@ -624,6 +713,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
624 fprintf(ofp, "common_nsecs, "); 713 fprintf(ofp, "common_nsecs, ");
625 fprintf(ofp, "common_pid, "); 714 fprintf(ofp, "common_pid, ");
626 fprintf(ofp, "common_comm,\n\t"); 715 fprintf(ofp, "common_comm,\n\t");
716 fprintf(ofp, "common_callchain, ");
627 717
628 not_first = 0; 718 not_first = 0;
629 count = 0; 719 count = 0;
@@ -667,7 +757,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
667 fprintf(ofp, "%%u"); 757 fprintf(ofp, "%%u");
668 } 758 }
669 759
670 fprintf(ofp, "\\n\" %% \\\n\t\t("); 760 fprintf(ofp, "\" %% \\\n\t\t(");
671 761
672 not_first = 0; 762 not_first = 0;
673 count = 0; 763 count = 0;
@@ -703,7 +793,15 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
703 fprintf(ofp, "%s", f->name); 793 fprintf(ofp, "%s", f->name);
704 } 794 }
705 795
706 fprintf(ofp, "),\n\n"); 796 fprintf(ofp, ")\n\n");
797
798 fprintf(ofp, "\t\tfor node in common_callchain:");
799 fprintf(ofp, "\n\t\t\tif 'sym' in node:");
800 fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])");
801 fprintf(ofp, "\n\t\t\telse:");
802 fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
803 fprintf(ofp, "\t\tprint \"\\n\"\n\n");
804
707 } 805 }
708 806
709 fprintf(ofp, "def trace_unhandled(event_name, context, " 807 fprintf(ofp, "def trace_unhandled(event_name, context, "