diff options
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 121 |
1 files changed, 54 insertions, 67 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index cbce2545da45..496f21cadd97 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "../../perf.h" | 29 | #include "../../perf.h" |
30 | #include "../debug.h" | 30 | #include "../debug.h" |
31 | #include "../callchain.h" | ||
31 | #include "../evsel.h" | 32 | #include "../evsel.h" |
32 | #include "../util.h" | 33 | #include "../util.h" |
33 | #include "../event.h" | 34 | #include "../event.h" |
@@ -73,6 +74,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj | |||
73 | Py_DECREF(val); | 74 | Py_DECREF(val); |
74 | } | 75 | } |
75 | 76 | ||
77 | static PyObject *get_handler(const char *handler_name) | ||
78 | { | ||
79 | PyObject *handler; | ||
80 | |||
81 | handler = PyDict_GetItemString(main_dict, handler_name); | ||
82 | if (handler && !PyCallable_Check(handler)) | ||
83 | return NULL; | ||
84 | return handler; | ||
85 | } | ||
86 | |||
87 | static void call_object(PyObject *handler, PyObject *args, const char *die_msg) | ||
88 | { | ||
89 | PyObject *retval; | ||
90 | |||
91 | retval = PyObject_CallObject(handler, args); | ||
92 | if (retval == NULL) | ||
93 | handler_call_die(die_msg); | ||
94 | Py_DECREF(retval); | ||
95 | } | ||
96 | |||
97 | static void try_call_object(const char *handler_name, PyObject *args) | ||
98 | { | ||
99 | PyObject *handler; | ||
100 | |||
101 | handler = get_handler(handler_name); | ||
102 | if (handler) | ||
103 | call_object(handler, args, handler_name); | ||
104 | } | ||
105 | |||
76 | static void define_value(enum print_arg_type field_type, | 106 | static void define_value(enum print_arg_type field_type, |
77 | const char *ev_name, | 107 | const char *ev_name, |
78 | const char *field_name, | 108 | const char *field_name, |
@@ -80,7 +110,7 @@ static void define_value(enum print_arg_type field_type, | |||
80 | const char *field_str) | 110 | const char *field_str) |
81 | { | 111 | { |
82 | const char *handler_name = "define_flag_value"; | 112 | const char *handler_name = "define_flag_value"; |
83 | PyObject *handler, *t, *retval; | 113 | PyObject *t; |
84 | unsigned long long value; | 114 | unsigned long long value; |
85 | unsigned n = 0; | 115 | unsigned n = 0; |
86 | 116 | ||
@@ -98,13 +128,7 @@ static void define_value(enum print_arg_type field_type, | |||
98 | PyTuple_SetItem(t, n++, PyInt_FromLong(value)); | 128 | PyTuple_SetItem(t, n++, PyInt_FromLong(value)); |
99 | PyTuple_SetItem(t, n++, PyString_FromString(field_str)); | 129 | PyTuple_SetItem(t, n++, PyString_FromString(field_str)); |
100 | 130 | ||
101 | handler = PyDict_GetItemString(main_dict, handler_name); | 131 | try_call_object(handler_name, t); |
102 | if (handler && PyCallable_Check(handler)) { | ||
103 | retval = PyObject_CallObject(handler, t); | ||
104 | if (retval == NULL) | ||
105 | handler_call_die(handler_name); | ||
106 | Py_DECREF(retval); | ||
107 | } | ||
108 | 132 | ||
109 | Py_DECREF(t); | 133 | Py_DECREF(t); |
110 | } | 134 | } |
@@ -127,7 +151,7 @@ static void define_field(enum print_arg_type field_type, | |||
127 | const char *delim) | 151 | const char *delim) |
128 | { | 152 | { |
129 | const char *handler_name = "define_flag_field"; | 153 | const char *handler_name = "define_flag_field"; |
130 | PyObject *handler, *t, *retval; | 154 | PyObject *t; |
131 | unsigned n = 0; | 155 | unsigned n = 0; |
132 | 156 | ||
133 | if (field_type == PRINT_SYMBOL) | 157 | if (field_type == PRINT_SYMBOL) |
@@ -145,13 +169,7 @@ static void define_field(enum print_arg_type field_type, | |||
145 | if (field_type == PRINT_FLAGS) | 169 | if (field_type == PRINT_FLAGS) |
146 | PyTuple_SetItem(t, n++, PyString_FromString(delim)); | 170 | PyTuple_SetItem(t, n++, PyString_FromString(delim)); |
147 | 171 | ||
148 | handler = PyDict_GetItemString(main_dict, handler_name); | 172 | try_call_object(handler_name, t); |
149 | if (handler && PyCallable_Check(handler)) { | ||
150 | retval = PyObject_CallObject(handler, t); | ||
151 | if (retval == NULL) | ||
152 | handler_call_die(handler_name); | ||
153 | Py_DECREF(retval); | ||
154 | } | ||
155 | 173 | ||
156 | Py_DECREF(t); | 174 | Py_DECREF(t); |
157 | } | 175 | } |
@@ -362,7 +380,7 @@ static void python_process_tracepoint(struct perf_sample *sample, | |||
362 | struct thread *thread, | 380 | struct thread *thread, |
363 | struct addr_location *al) | 381 | struct addr_location *al) |
364 | { | 382 | { |
365 | PyObject *handler, *retval, *context, *t, *obj, *callchain; | 383 | PyObject *handler, *context, *t, *obj, *callchain; |
366 | PyObject *dict = NULL; | 384 | PyObject *dict = NULL; |
367 | static char handler_name[256]; | 385 | static char handler_name[256]; |
368 | struct format_field *field; | 386 | struct format_field *field; |
@@ -387,9 +405,7 @@ static void python_process_tracepoint(struct perf_sample *sample, | |||
387 | 405 | ||
388 | sprintf(handler_name, "%s__%s", event->system, event->name); | 406 | sprintf(handler_name, "%s__%s", event->system, event->name); |
389 | 407 | ||
390 | handler = PyDict_GetItemString(main_dict, handler_name); | 408 | handler = get_handler(handler_name); |
391 | if (handler && !PyCallable_Check(handler)) | ||
392 | handler = NULL; | ||
393 | if (!handler) { | 409 | if (!handler) { |
394 | dict = PyDict_New(); | 410 | dict = PyDict_New(); |
395 | if (!dict) | 411 | if (!dict) |
@@ -450,19 +466,9 @@ static void python_process_tracepoint(struct perf_sample *sample, | |||
450 | Py_FatalError("error resizing Python tuple"); | 466 | Py_FatalError("error resizing Python tuple"); |
451 | 467 | ||
452 | if (handler) { | 468 | if (handler) { |
453 | retval = PyObject_CallObject(handler, t); | 469 | call_object(handler, t, handler_name); |
454 | if (retval == NULL) | ||
455 | handler_call_die(handler_name); | ||
456 | Py_DECREF(retval); | ||
457 | } else { | 470 | } else { |
458 | handler = PyDict_GetItemString(main_dict, "trace_unhandled"); | 471 | try_call_object("trace_unhandled", t); |
459 | if (handler && PyCallable_Check(handler)) { | ||
460 | |||
461 | retval = PyObject_CallObject(handler, t); | ||
462 | if (retval == NULL) | ||
463 | handler_call_die("trace_unhandled"); | ||
464 | Py_DECREF(retval); | ||
465 | } | ||
466 | Py_DECREF(dict); | 472 | Py_DECREF(dict); |
467 | } | 473 | } |
468 | 474 | ||
@@ -474,7 +480,7 @@ static void python_process_general_event(struct perf_sample *sample, | |||
474 | struct thread *thread, | 480 | struct thread *thread, |
475 | struct addr_location *al) | 481 | struct addr_location *al) |
476 | { | 482 | { |
477 | PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; | 483 | PyObject *handler, *t, *dict, *callchain, *dict_sample; |
478 | static char handler_name[64]; | 484 | static char handler_name[64]; |
479 | unsigned n = 0; | 485 | unsigned n = 0; |
480 | 486 | ||
@@ -496,8 +502,8 @@ static void python_process_general_event(struct perf_sample *sample, | |||
496 | 502 | ||
497 | snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); | 503 | snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); |
498 | 504 | ||
499 | handler = PyDict_GetItemString(main_dict, handler_name); | 505 | handler = get_handler(handler_name); |
500 | if (!handler || !PyCallable_Check(handler)) | 506 | if (!handler) |
501 | goto exit; | 507 | goto exit; |
502 | 508 | ||
503 | pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); | 509 | pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); |
@@ -539,10 +545,7 @@ static void python_process_general_event(struct perf_sample *sample, | |||
539 | if (_PyTuple_Resize(&t, n) == -1) | 545 | if (_PyTuple_Resize(&t, n) == -1) |
540 | Py_FatalError("error resizing Python tuple"); | 546 | Py_FatalError("error resizing Python tuple"); |
541 | 547 | ||
542 | retval = PyObject_CallObject(handler, t); | 548 | call_object(handler, t, handler_name); |
543 | if (retval == NULL) | ||
544 | handler_call_die(handler_name); | ||
545 | Py_DECREF(retval); | ||
546 | exit: | 549 | exit: |
547 | Py_DECREF(dict); | 550 | Py_DECREF(dict); |
548 | Py_DECREF(t); | 551 | Py_DECREF(t); |
@@ -566,36 +569,24 @@ static void python_process_event(union perf_event *event __maybe_unused, | |||
566 | 569 | ||
567 | static int run_start_sub(void) | 570 | static int run_start_sub(void) |
568 | { | 571 | { |
569 | PyObject *handler, *retval; | ||
570 | int err = 0; | ||
571 | |||
572 | main_module = PyImport_AddModule("__main__"); | 572 | main_module = PyImport_AddModule("__main__"); |
573 | if (main_module == NULL) | 573 | if (main_module == NULL) |
574 | return -1; | 574 | return -1; |
575 | Py_INCREF(main_module); | 575 | Py_INCREF(main_module); |
576 | 576 | ||
577 | main_dict = PyModule_GetDict(main_module); | 577 | main_dict = PyModule_GetDict(main_module); |
578 | if (main_dict == NULL) { | 578 | if (main_dict == NULL) |
579 | err = -1; | ||
580 | goto error; | 579 | goto error; |
581 | } | ||
582 | Py_INCREF(main_dict); | 580 | Py_INCREF(main_dict); |
583 | 581 | ||
584 | handler = PyDict_GetItemString(main_dict, "trace_begin"); | 582 | try_call_object("trace_begin", NULL); |
585 | if (handler == NULL || !PyCallable_Check(handler)) | ||
586 | goto out; | ||
587 | 583 | ||
588 | retval = PyObject_CallObject(handler, NULL); | 584 | return 0; |
589 | if (retval == NULL) | ||
590 | handler_call_die("trace_begin"); | ||
591 | 585 | ||
592 | Py_DECREF(retval); | ||
593 | return err; | ||
594 | error: | 586 | error: |
595 | Py_XDECREF(main_dict); | 587 | Py_XDECREF(main_dict); |
596 | Py_XDECREF(main_module); | 588 | Py_XDECREF(main_module); |
597 | out: | 589 | return -1; |
598 | return err; | ||
599 | } | 590 | } |
600 | 591 | ||
601 | /* | 592 | /* |
@@ -649,28 +640,23 @@ error: | |||
649 | return err; | 640 | return err; |
650 | } | 641 | } |
651 | 642 | ||
643 | static int python_flush_script(void) | ||
644 | { | ||
645 | return 0; | ||
646 | } | ||
647 | |||
652 | /* | 648 | /* |
653 | * Stop trace script | 649 | * Stop trace script |
654 | */ | 650 | */ |
655 | static int python_stop_script(void) | 651 | static int python_stop_script(void) |
656 | { | 652 | { |
657 | PyObject *handler, *retval; | 653 | try_call_object("trace_end", NULL); |
658 | int err = 0; | ||
659 | 654 | ||
660 | handler = PyDict_GetItemString(main_dict, "trace_end"); | ||
661 | if (handler == NULL || !PyCallable_Check(handler)) | ||
662 | goto out; | ||
663 | |||
664 | retval = PyObject_CallObject(handler, NULL); | ||
665 | if (retval == NULL) | ||
666 | handler_call_die("trace_end"); | ||
667 | Py_DECREF(retval); | ||
668 | out: | ||
669 | Py_XDECREF(main_dict); | 655 | Py_XDECREF(main_dict); |
670 | Py_XDECREF(main_module); | 656 | Py_XDECREF(main_module); |
671 | Py_Finalize(); | 657 | Py_Finalize(); |
672 | 658 | ||
673 | return err; | 659 | return 0; |
674 | } | 660 | } |
675 | 661 | ||
676 | static int python_generate_script(struct pevent *pevent, const char *outfile) | 662 | static int python_generate_script(struct pevent *pevent, const char *outfile) |
@@ -843,6 +829,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) | |||
843 | struct scripting_ops python_scripting_ops = { | 829 | struct scripting_ops python_scripting_ops = { |
844 | .name = "Python", | 830 | .name = "Python", |
845 | .start_script = python_start_script, | 831 | .start_script = python_start_script, |
832 | .flush_script = python_flush_script, | ||
846 | .stop_script = python_stop_script, | 833 | .stop_script = python_stop_script, |
847 | .process_event = python_process_event, | 834 | .process_event = python_process_event, |
848 | .generate_script = python_generate_script, | 835 | .generate_script = python_generate_script, |