aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorArun Kalyanasundaram <arunkaly@google.com>2017-07-21 18:04:21 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-07-25 21:43:20 -0400
commitf38d281663b011d1d8a1b0119bb8357706d134a8 (patch)
tree5a33f1bf722a5a1b4bd33faed9c2cbcf66d9d59f /tools/perf/util/scripting-engines/trace-event-python.c
parent74ec14f3893c3065053b91cec850cffa2d565e0a (diff)
perf script python: Add perf_sample dict to tracepoint handlers
The process_event python hook receives a dict with all perf_sample entries, but the tracepoint specific and trace_unhandled hooks predate the introduction of this dict, and do not receive it. Add the aforementioned dict as an additional argument to the affected handlers. To keep backwards compatibility (and avoid unnecessary work), do not pass the dict if the number of arguments signals that handler version predates this change. Signed-off-by: Arun Kalyanasundaram <arunkaly@google.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Carrillo-Cisneros <davidcc@google.com> Cc: David S. Miller <davem@davemloft.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Seongjae Park <sj38.park@gmail.com> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/20170721220422.63962-5-arunkaly@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 55a45784c910..938b39f6ad31 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -116,6 +116,34 @@ static PyObject *get_handler(const char *handler_name)
116 return handler; 116 return handler;
117} 117}
118 118
119static int get_argument_count(PyObject *handler)
120{
121 int arg_count = 0;
122
123 /*
124 * The attribute for the code object is func_code in Python 2,
125 * whereas it is __code__ in Python 3.0+.
126 */
127 PyObject *code_obj = PyObject_GetAttrString(handler,
128 "func_code");
129 if (PyErr_Occurred()) {
130 PyErr_Clear();
131 code_obj = PyObject_GetAttrString(handler,
132 "__code__");
133 }
134 PyErr_Clear();
135 if (code_obj) {
136 PyObject *arg_count_obj = PyObject_GetAttrString(code_obj,
137 "co_argcount");
138 if (arg_count_obj) {
139 arg_count = (int) PyInt_AsLong(arg_count_obj);
140 Py_DECREF(arg_count_obj);
141 }
142 Py_DECREF(code_obj);
143 }
144 return arg_count;
145}
146
119static void call_object(PyObject *handler, PyObject *args, const char *die_msg) 147static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
120{ 148{
121 PyObject *retval; 149 PyObject *retval;
@@ -499,7 +527,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
499{ 527{
500 struct event_format *event = evsel->tp_format; 528 struct event_format *event = evsel->tp_format;
501 PyObject *handler, *context, *t, *obj = NULL, *callchain; 529 PyObject *handler, *context, *t, *obj = NULL, *callchain;
502 PyObject *dict = NULL; 530 PyObject *dict = NULL, *all_entries_dict = NULL;
503 static char handler_name[256]; 531 static char handler_name[256];
504 struct format_field *field; 532 struct format_field *field;
505 unsigned long s, ns; 533 unsigned long s, ns;
@@ -552,6 +580,8 @@ static void python_process_tracepoint(struct perf_sample *sample,
552 580
553 /* ip unwinding */ 581 /* ip unwinding */
554 callchain = python_process_callchain(sample, evsel, al); 582 callchain = python_process_callchain(sample, evsel, al);
583 /* Need an additional reference for the perf_sample dict */
584 Py_INCREF(callchain);
555 585
556 if (!dict) { 586 if (!dict) {
557 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 587 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
@@ -602,6 +632,14 @@ static void python_process_tracepoint(struct perf_sample *sample,
602 if (dict) 632 if (dict)
603 PyTuple_SetItem(t, n++, dict); 633 PyTuple_SetItem(t, n++, dict);
604 634
635 if (get_argument_count(handler) == (int) n + 1) {
636 all_entries_dict = get_perf_sample_dict(sample, evsel, al,
637 callchain);
638 PyTuple_SetItem(t, n++, all_entries_dict);
639 } else {
640 Py_DECREF(callchain);
641 }
642
605 if (_PyTuple_Resize(&t, n) == -1) 643 if (_PyTuple_Resize(&t, n) == -1)
606 Py_FatalError("error resizing Python tuple"); 644 Py_FatalError("error resizing Python tuple");
607 645
@@ -612,6 +650,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
612 Py_DECREF(dict); 650 Py_DECREF(dict);
613 } 651 }
614 652
653 Py_XDECREF(all_entries_dict);
615 Py_DECREF(t); 654 Py_DECREF(t);
616} 655}
617 656