aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-10-03 14:24:46 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-10-03 14:24:46 -0400
commit447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6 (patch)
tree676e741f2552c9cb301e1e49c557b92bf8940f55 /tools/perf/util/scripting-engines/trace-event-python.c
parent3049683eafdbbbd7350b0e5ca02a2d8c026a3362 (diff)
parent042e1c79166b9250edd8262bea84e1703f27ad2e (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.18.
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c197
1 files changed, 174 insertions, 23 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 1c419321f707..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);
@@ -231,15 +239,133 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
231 return event; 239 return event;
232} 240}
233 241
242static PyObject *get_field_numeric_entry(struct event_format *event,
243 struct format_field *field, void *data)
244{
245 bool is_array = field->flags & FIELD_IS_ARRAY;
246 PyObject *obj, *list = NULL;
247 unsigned long long val;
248 unsigned int item_size, n_items, i;
249
250 if (is_array) {
251 list = PyList_New(field->arraylen);
252 item_size = field->size / field->arraylen;
253 n_items = field->arraylen;
254 } else {
255 item_size = field->size;
256 n_items = 1;
257 }
258
259 for (i = 0; i < n_items; i++) {
260
261 val = read_size(event, data + field->offset + i * item_size,
262 item_size);
263 if (field->flags & FIELD_IS_SIGNED) {
264 if ((long long)val >= LONG_MIN &&
265 (long long)val <= LONG_MAX)
266 obj = PyInt_FromLong(val);
267 else
268 obj = PyLong_FromLongLong(val);
269 } else {
270 if (val <= LONG_MAX)
271 obj = PyInt_FromLong(val);
272 else
273 obj = PyLong_FromUnsignedLongLong(val);
274 }
275 if (is_array)
276 PyList_SET_ITEM(list, i, obj);
277 }
278 if (is_array)
279 obj = list;
280 return obj;
281}
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
234static void python_process_tracepoint(struct perf_sample *sample, 360static void python_process_tracepoint(struct perf_sample *sample,
235 struct perf_evsel *evsel, 361 struct perf_evsel *evsel,
236 struct thread *thread, 362 struct thread *thread,
237 struct addr_location *al) 363 struct addr_location *al)
238{ 364{
239 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 365 PyObject *handler, *retval, *context, *t, *obj, *callchain;
366 PyObject *dict = NULL;
240 static char handler_name[256]; 367 static char handler_name[256];
241 struct format_field *field; 368 struct format_field *field;
242 unsigned long long val;
243 unsigned long s, ns; 369 unsigned long s, ns;
244 struct event_format *event; 370 struct event_format *event;
245 unsigned n = 0; 371 unsigned n = 0;
@@ -280,18 +406,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
280 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 406 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
281 PyTuple_SetItem(t, n++, context); 407 PyTuple_SetItem(t, n++, context);
282 408
409 /* ip unwinding */
410 callchain = python_process_callchain(sample, evsel, al);
411
283 if (handler) { 412 if (handler) {
284 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 413 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
285 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 414 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
286 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 415 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
287 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 416 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
288 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 417 PyTuple_SetItem(t, n++, PyString_FromString(comm));
418 PyTuple_SetItem(t, n++, callchain);
289 } else { 419 } else {
290 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 420 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
291 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 421 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
292 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 422 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
293 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 423 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
294 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);
295 } 426 }
296 for (field = event->format.fields; field; field = field->next) { 427 for (field = event->format.fields; field; field = field->next) {
297 if (field->flags & FIELD_IS_STRING) { 428 if (field->flags & FIELD_IS_STRING) {
@@ -303,20 +434,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
303 offset = field->offset; 434 offset = field->offset;
304 obj = PyString_FromString((char *)data + offset); 435 obj = PyString_FromString((char *)data + offset);
305 } else { /* FIELD_IS_NUMERIC */ 436 } else { /* FIELD_IS_NUMERIC */
306 val = read_size(event, data + field->offset, 437 obj = get_field_numeric_entry(event, field, data);
307 field->size);
308 if (field->flags & FIELD_IS_SIGNED) {
309 if ((long long)val >= LONG_MIN &&
310 (long long)val <= LONG_MAX)
311 obj = PyInt_FromLong(val);
312 else
313 obj = PyLong_FromLongLong(val);
314 } else {
315 if (val <= LONG_MAX)
316 obj = PyInt_FromLong(val);
317 else
318 obj = PyLong_FromUnsignedLongLong(val);
319 }
320 } 438 }
321 if (handler) 439 if (handler)
322 PyTuple_SetItem(t, n++, obj); 440 PyTuple_SetItem(t, n++, obj);
@@ -324,6 +442,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
324 pydict_set_item_string_decref(dict, field->name, obj); 442 pydict_set_item_string_decref(dict, field->name, obj);
325 443
326 } 444 }
445
327 if (!handler) 446 if (!handler)
328 PyTuple_SetItem(t, n++, dict); 447 PyTuple_SetItem(t, n++, dict);
329 448
@@ -334,6 +453,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
334 retval = PyObject_CallObject(handler, t); 453 retval = PyObject_CallObject(handler, t);
335 if (retval == NULL) 454 if (retval == NULL)
336 handler_call_die(handler_name); 455 handler_call_die(handler_name);
456 Py_DECREF(retval);
337 } else { 457 } else {
338 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 458 handler = PyDict_GetItemString(main_dict, "trace_unhandled");
339 if (handler && PyCallable_Check(handler)) { 459 if (handler && PyCallable_Check(handler)) {
@@ -341,6 +461,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
341 retval = PyObject_CallObject(handler, t); 461 retval = PyObject_CallObject(handler, t);
342 if (retval == NULL) 462 if (retval == NULL)
343 handler_call_die("trace_unhandled"); 463 handler_call_die("trace_unhandled");
464 Py_DECREF(retval);
344 } 465 }
345 Py_DECREF(dict); 466 Py_DECREF(dict);
346 } 467 }
@@ -353,7 +474,7 @@ static void python_process_general_event(struct perf_sample *sample,
353 struct thread *thread, 474 struct thread *thread,
354 struct addr_location *al) 475 struct addr_location *al)
355{ 476{
356 PyObject *handler, *retval, *t, *dict; 477 PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample;
357 static char handler_name[64]; 478 static char handler_name[64];
358 unsigned n = 0; 479 unsigned n = 0;
359 480
@@ -369,6 +490,10 @@ static void python_process_general_event(struct perf_sample *sample,
369 if (!dict) 490 if (!dict)
370 Py_FatalError("couldn't create Python dictionary"); 491 Py_FatalError("couldn't create Python dictionary");
371 492
493 dict_sample = PyDict_New();
494 if (!dict_sample)
495 Py_FatalError("couldn't create Python dictionary");
496
372 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 497 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
373 498
374 handler = PyDict_GetItemString(main_dict, handler_name); 499 handler = PyDict_GetItemString(main_dict, handler_name);
@@ -378,8 +503,21 @@ static void python_process_general_event(struct perf_sample *sample,
378 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)));
379 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( 504 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
380 (const char *)&evsel->attr, sizeof(evsel->attr))); 505 (const char *)&evsel->attr, sizeof(evsel->attr)));
381 pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize( 506
382 (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
383 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( 521 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
384 (const char *)sample->raw_data, sample->raw_size)); 522 (const char *)sample->raw_data, sample->raw_size));
385 pydict_set_item_string_decref(dict, "comm", 523 pydict_set_item_string_decref(dict, "comm",
@@ -393,6 +531,10 @@ static void python_process_general_event(struct perf_sample *sample,
393 PyString_FromString(al->sym->name)); 531 PyString_FromString(al->sym->name));
394 } 532 }
395 533
534 /* ip unwinding */
535 callchain = python_process_callchain(sample, evsel, al);
536 pydict_set_item_string_decref(dict, "callchain", callchain);
537
396 PyTuple_SetItem(t, n++, dict); 538 PyTuple_SetItem(t, n++, dict);
397 if (_PyTuple_Resize(&t, n) == -1) 539 if (_PyTuple_Resize(&t, n) == -1)
398 Py_FatalError("error resizing Python tuple"); 540 Py_FatalError("error resizing Python tuple");
@@ -400,6 +542,7 @@ static void python_process_general_event(struct perf_sample *sample,
400 retval = PyObject_CallObject(handler, t); 542 retval = PyObject_CallObject(handler, t);
401 if (retval == NULL) 543 if (retval == NULL)
402 handler_call_die(handler_name); 544 handler_call_die(handler_name);
545 Py_DECREF(retval);
403exit: 546exit:
404 Py_DECREF(dict); 547 Py_DECREF(dict);
405 Py_DECREF(t); 548 Py_DECREF(t);
@@ -521,8 +664,7 @@ static int python_stop_script(void)
521 retval = PyObject_CallObject(handler, NULL); 664 retval = PyObject_CallObject(handler, NULL);
522 if (retval == NULL) 665 if (retval == NULL)
523 handler_call_die("trace_end"); 666 handler_call_die("trace_end");
524 else 667 Py_DECREF(retval);
525 Py_DECREF(retval);
526out: 668out:
527 Py_XDECREF(main_dict); 669 Py_XDECREF(main_dict);
528 Py_XDECREF(main_module); 670 Py_XDECREF(main_module);
@@ -589,6 +731,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
589 fprintf(ofp, "common_nsecs, "); 731 fprintf(ofp, "common_nsecs, ");
590 fprintf(ofp, "common_pid, "); 732 fprintf(ofp, "common_pid, ");
591 fprintf(ofp, "common_comm,\n\t"); 733 fprintf(ofp, "common_comm,\n\t");
734 fprintf(ofp, "common_callchain, ");
592 735
593 not_first = 0; 736 not_first = 0;
594 count = 0; 737 count = 0;
@@ -632,7 +775,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
632 fprintf(ofp, "%%u"); 775 fprintf(ofp, "%%u");
633 } 776 }
634 777
635 fprintf(ofp, "\\n\" %% \\\n\t\t("); 778 fprintf(ofp, "\" %% \\\n\t\t(");
636 779
637 not_first = 0; 780 not_first = 0;
638 count = 0; 781 count = 0;
@@ -668,7 +811,15 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
668 fprintf(ofp, "%s", f->name); 811 fprintf(ofp, "%s", f->name);
669 } 812 }
670 813
671 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
672 } 823 }
673 824
674 fprintf(ofp, "def trace_unhandled(event_name, context, " 825 fprintf(ofp, "def trace_unhandled(event_name, context, "