aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-07-18 00:16:06 -0400
committerIngo Molnar <mingo@kernel.org>2014-07-18 00:16:06 -0400
commitec6dbcb7ade2a616675cbe3185cf299ee1615c9f (patch)
tree4953f7eca477e011aa9e16cdb236220ed9cec4be /tools/perf/util/scripting-engines/trace-event-python.c
parentff2ebe46e15bd49d52b9c2f3fc77f3a9d94eac7b (diff)
parent0b437860818dc717f6a9e8a5089223a8414f5fff (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: o Support S/390 in 'perf kvm stat' (Alexander Yarygin) Developer Stuff: o Various fixes and prep work related to supporting Intel PT (Adrian Hunter) o Introduce multiple debug variables control (Jiri Olsa) o Add callchain and additional sample information for python scripts (Joseph Schuchart) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c140
1 files changed, 132 insertions, 8 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index e55b65a65558..cbce2545da45 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -27,11 +27,13 @@
27#include <errno.h> 27#include <errno.h>
28 28
29#include "../../perf.h" 29#include "../../perf.h"
30#include "../debug.h"
30#include "../evsel.h" 31#include "../evsel.h"
31#include "../util.h" 32#include "../util.h"
32#include "../event.h" 33#include "../event.h"
33#include "../thread.h" 34#include "../thread.h"
34#include "../trace-event.h" 35#include "../trace-event.h"
36#include "../machine.h"
35 37
36PyMODINIT_FUNC initperf_trace_context(void); 38PyMODINIT_FUNC initperf_trace_context(void);
37 39
@@ -50,10 +52,14 @@ static int zero_flag_atom;
50 52
51static PyObject *main_module, *main_dict; 53static PyObject *main_module, *main_dict;
52 54
55static void handler_call_die(const char *handler_name) NORETURN;
53static void handler_call_die(const char *handler_name) 56static void handler_call_die(const char *handler_name)
54{ 57{
55 PyErr_Print(); 58 PyErr_Print();
56 Py_FatalError("problem in Python trace event handler"); 59 Py_FatalError("problem in Python trace event handler");
60 // Py_FatalError does not return
61 // but we have to make the compiler happy
62 abort();
57} 63}
58 64
59/* 65/*
@@ -97,6 +103,7 @@ static void define_value(enum print_arg_type field_type,
97 retval = PyObject_CallObject(handler, t); 103 retval = PyObject_CallObject(handler, t);
98 if (retval == NULL) 104 if (retval == NULL)
99 handler_call_die(handler_name); 105 handler_call_die(handler_name);
106 Py_DECREF(retval);
100 } 107 }
101 108
102 Py_DECREF(t); 109 Py_DECREF(t);
@@ -143,6 +150,7 @@ static void define_field(enum print_arg_type field_type,
143 retval = PyObject_CallObject(handler, t); 150 retval = PyObject_CallObject(handler, t);
144 if (retval == NULL) 151 if (retval == NULL)
145 handler_call_die(handler_name); 152 handler_call_die(handler_name);
153 Py_DECREF(retval);
146 } 154 }
147 155
148 Py_DECREF(t); 156 Py_DECREF(t);
@@ -272,12 +280,90 @@ static PyObject *get_field_numeric_entry(struct event_format *event,
272 return obj; 280 return obj;
273} 281}
274 282
283
284static PyObject *python_process_callchain(struct perf_sample *sample,
285 struct perf_evsel *evsel,
286 struct addr_location *al)
287{
288 PyObject *pylist;
289
290 pylist = PyList_New(0);
291 if (!pylist)
292 Py_FatalError("couldn't create Python list");
293
294 if (!symbol_conf.use_callchain || !sample->callchain)
295 goto exit;
296
297 if (machine__resolve_callchain(al->machine, evsel, al->thread,
298 sample, NULL, NULL,
299 PERF_MAX_STACK_DEPTH) != 0) {
300 pr_err("Failed to resolve callchain. Skipping\n");
301 goto exit;
302 }
303 callchain_cursor_commit(&callchain_cursor);
304
305
306 while (1) {
307 PyObject *pyelem;
308 struct callchain_cursor_node *node;
309 node = callchain_cursor_current(&callchain_cursor);
310 if (!node)
311 break;
312
313 pyelem = PyDict_New();
314 if (!pyelem)
315 Py_FatalError("couldn't create Python dictionary");
316
317
318 pydict_set_item_string_decref(pyelem, "ip",
319 PyLong_FromUnsignedLongLong(node->ip));
320
321 if (node->sym) {
322 PyObject *pysym = PyDict_New();
323 if (!pysym)
324 Py_FatalError("couldn't create Python dictionary");
325 pydict_set_item_string_decref(pysym, "start",
326 PyLong_FromUnsignedLongLong(node->sym->start));
327 pydict_set_item_string_decref(pysym, "end",
328 PyLong_FromUnsignedLongLong(node->sym->end));
329 pydict_set_item_string_decref(pysym, "binding",
330 PyInt_FromLong(node->sym->binding));
331 pydict_set_item_string_decref(pysym, "name",
332 PyString_FromStringAndSize(node->sym->name,
333 node->sym->namelen));
334 pydict_set_item_string_decref(pyelem, "sym", pysym);
335 }
336
337 if (node->map) {
338 struct map *map = node->map;
339 const char *dsoname = "[unknown]";
340 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
341 if (symbol_conf.show_kernel_path && map->dso->long_name)
342 dsoname = map->dso->long_name;
343 else if (map->dso->name)
344 dsoname = map->dso->name;
345 }
346 pydict_set_item_string_decref(pyelem, "dso",
347 PyString_FromString(dsoname));
348 }
349
350 callchain_cursor_advance(&callchain_cursor);
351 PyList_Append(pylist, pyelem);
352 Py_DECREF(pyelem);
353 }
354
355exit:
356 return pylist;
357}
358
359
275static void python_process_tracepoint(struct perf_sample *sample, 360static void python_process_tracepoint(struct perf_sample *sample,
276 struct perf_evsel *evsel, 361 struct perf_evsel *evsel,
277 struct thread *thread, 362 struct thread *thread,
278 struct addr_location *al) 363 struct addr_location *al)
279{ 364{
280 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 365 PyObject *handler, *retval, *context, *t, *obj, *callchain;
366 PyObject *dict = NULL;
281 static char handler_name[256]; 367 static char handler_name[256];
282 struct format_field *field; 368 struct format_field *field;
283 unsigned long s, ns; 369 unsigned long s, ns;
@@ -320,18 +406,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
320 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 406 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
321 PyTuple_SetItem(t, n++, context); 407 PyTuple_SetItem(t, n++, context);
322 408
409 /* ip unwinding */
410 callchain = python_process_callchain(sample, evsel, al);
411
323 if (handler) { 412 if (handler) {
324 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 413 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
325 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 414 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
326 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 415 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
327 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 416 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
328 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 417 PyTuple_SetItem(t, n++, PyString_FromString(comm));
418 PyTuple_SetItem(t, n++, callchain);
329 } else { 419 } else {
330 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 420 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
331 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 421 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
332 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 422 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
333 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 423 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
334 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); 424 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
425 pydict_set_item_string_decref(dict, "common_callchain", callchain);
335 } 426 }
336 for (field = event->format.fields; field; field = field->next) { 427 for (field = event->format.fields; field; field = field->next) {
337 if (field->flags & FIELD_IS_STRING) { 428 if (field->flags & FIELD_IS_STRING) {
@@ -351,6 +442,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
351 pydict_set_item_string_decref(dict, field->name, obj); 442 pydict_set_item_string_decref(dict, field->name, obj);
352 443
353 } 444 }
445
354 if (!handler) 446 if (!handler)
355 PyTuple_SetItem(t, n++, dict); 447 PyTuple_SetItem(t, n++, dict);
356 448
@@ -361,6 +453,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
361 retval = PyObject_CallObject(handler, t); 453 retval = PyObject_CallObject(handler, t);
362 if (retval == NULL) 454 if (retval == NULL)
363 handler_call_die(handler_name); 455 handler_call_die(handler_name);
456 Py_DECREF(retval);
364 } else { 457 } else {
365 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 458 handler = PyDict_GetItemString(main_dict, "trace_unhandled");
366 if (handler && PyCallable_Check(handler)) { 459 if (handler && PyCallable_Check(handler)) {
@@ -368,6 +461,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
368 retval = PyObject_CallObject(handler, t); 461 retval = PyObject_CallObject(handler, t);
369 if (retval == NULL) 462 if (retval == NULL)
370 handler_call_die("trace_unhandled"); 463 handler_call_die("trace_unhandled");
464 Py_DECREF(retval);
371 } 465 }
372 Py_DECREF(dict); 466 Py_DECREF(dict);
373 } 467 }
@@ -380,7 +474,7 @@ static void python_process_general_event(struct perf_sample *sample,
380 struct thread *thread, 474 struct thread *thread,
381 struct addr_location *al) 475 struct addr_location *al)
382{ 476{
383 PyObject *handler, *retval, *t, *dict; 477 PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample;
384 static char handler_name[64]; 478 static char handler_name[64];
385 unsigned n = 0; 479 unsigned n = 0;
386 480
@@ -396,6 +490,10 @@ static void python_process_general_event(struct perf_sample *sample,
396 if (!dict) 490 if (!dict)
397 Py_FatalError("couldn't create Python dictionary"); 491 Py_FatalError("couldn't create Python dictionary");
398 492
493 dict_sample = PyDict_New();
494 if (!dict_sample)
495 Py_FatalError("couldn't create Python dictionary");
496
399 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 497 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
400 498
401 handler = PyDict_GetItemString(main_dict, handler_name); 499 handler = PyDict_GetItemString(main_dict, handler_name);
@@ -405,8 +503,21 @@ static void python_process_general_event(struct perf_sample *sample,
405 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 503 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
406 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( 504 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
407 (const char *)&evsel->attr, sizeof(evsel->attr))); 505 (const char *)&evsel->attr, sizeof(evsel->attr)));
408 pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize( 506
409 (const char *)sample, sizeof(*sample))); 507 pydict_set_item_string_decref(dict_sample, "pid",
508 PyInt_FromLong(sample->pid));
509 pydict_set_item_string_decref(dict_sample, "tid",
510 PyInt_FromLong(sample->tid));
511 pydict_set_item_string_decref(dict_sample, "cpu",
512 PyInt_FromLong(sample->cpu));
513 pydict_set_item_string_decref(dict_sample, "ip",
514 PyLong_FromUnsignedLongLong(sample->ip));
515 pydict_set_item_string_decref(dict_sample, "time",
516 PyLong_FromUnsignedLongLong(sample->time));
517 pydict_set_item_string_decref(dict_sample, "period",
518 PyLong_FromUnsignedLongLong(sample->period));
519 pydict_set_item_string_decref(dict, "sample", dict_sample);
520
410 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( 521 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
411 (const char *)sample->raw_data, sample->raw_size)); 522 (const char *)sample->raw_data, sample->raw_size));
412 pydict_set_item_string_decref(dict, "comm", 523 pydict_set_item_string_decref(dict, "comm",
@@ -420,6 +531,10 @@ static void python_process_general_event(struct perf_sample *sample,
420 PyString_FromString(al->sym->name)); 531 PyString_FromString(al->sym->name));
421 } 532 }
422 533
534 /* ip unwinding */
535 callchain = python_process_callchain(sample, evsel, al);
536 pydict_set_item_string_decref(dict, "callchain", callchain);
537
423 PyTuple_SetItem(t, n++, dict); 538 PyTuple_SetItem(t, n++, dict);
424 if (_PyTuple_Resize(&t, n) == -1) 539 if (_PyTuple_Resize(&t, n) == -1)
425 Py_FatalError("error resizing Python tuple"); 540 Py_FatalError("error resizing Python tuple");
@@ -427,6 +542,7 @@ static void python_process_general_event(struct perf_sample *sample,
427 retval = PyObject_CallObject(handler, t); 542 retval = PyObject_CallObject(handler, t);
428 if (retval == NULL) 543 if (retval == NULL)
429 handler_call_die(handler_name); 544 handler_call_die(handler_name);
545 Py_DECREF(retval);
430exit: 546exit:
431 Py_DECREF(dict); 547 Py_DECREF(dict);
432 Py_DECREF(t); 548 Py_DECREF(t);
@@ -548,8 +664,7 @@ static int python_stop_script(void)
548 retval = PyObject_CallObject(handler, NULL); 664 retval = PyObject_CallObject(handler, NULL);
549 if (retval == NULL) 665 if (retval == NULL)
550 handler_call_die("trace_end"); 666 handler_call_die("trace_end");
551 else 667 Py_DECREF(retval);
552 Py_DECREF(retval);
553out: 668out:
554 Py_XDECREF(main_dict); 669 Py_XDECREF(main_dict);
555 Py_XDECREF(main_module); 670 Py_XDECREF(main_module);
@@ -616,6 +731,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
616 fprintf(ofp, "common_nsecs, "); 731 fprintf(ofp, "common_nsecs, ");
617 fprintf(ofp, "common_pid, "); 732 fprintf(ofp, "common_pid, ");
618 fprintf(ofp, "common_comm,\n\t"); 733 fprintf(ofp, "common_comm,\n\t");
734 fprintf(ofp, "common_callchain, ");
619 735
620 not_first = 0; 736 not_first = 0;
621 count = 0; 737 count = 0;
@@ -659,7 +775,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
659 fprintf(ofp, "%%u"); 775 fprintf(ofp, "%%u");
660 } 776 }
661 777
662 fprintf(ofp, "\\n\" %% \\\n\t\t("); 778 fprintf(ofp, "\" %% \\\n\t\t(");
663 779
664 not_first = 0; 780 not_first = 0;
665 count = 0; 781 count = 0;
@@ -695,7 +811,15 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
695 fprintf(ofp, "%s", f->name); 811 fprintf(ofp, "%s", f->name);
696 } 812 }
697 813
698 fprintf(ofp, "),\n\n"); 814 fprintf(ofp, ")\n\n");
815
816 fprintf(ofp, "\t\tfor node in common_callchain:");
817 fprintf(ofp, "\n\t\t\tif 'sym' in node:");
818 fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])");
819 fprintf(ofp, "\n\t\t\telse:");
820 fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
821 fprintf(ofp, "\t\tprint \"\\n\"\n\n");
822
699 } 823 }
700 824
701 fprintf(ofp, "def trace_unhandled(event_name, context, " 825 fprintf(ofp, "def trace_unhandled(event_name, context, "