17e4b21b8STom Zanussi /* 27e4b21b8STom Zanussi * trace-event-python. Feed trace events to an embedded Python interpreter. 37e4b21b8STom Zanussi * 47e4b21b8STom Zanussi * Copyright (C) 2010 Tom Zanussi <[email protected]> 57e4b21b8STom Zanussi * 67e4b21b8STom Zanussi * This program is free software; you can redistribute it and/or modify 77e4b21b8STom Zanussi * it under the terms of the GNU General Public License as published by 87e4b21b8STom Zanussi * the Free Software Foundation; either version 2 of the License, or 97e4b21b8STom Zanussi * (at your option) any later version. 107e4b21b8STom Zanussi * 117e4b21b8STom Zanussi * This program is distributed in the hope that it will be useful, 127e4b21b8STom Zanussi * but WITHOUT ANY WARRANTY; without even the implied warranty of 137e4b21b8STom Zanussi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 147e4b21b8STom Zanussi * GNU General Public License for more details. 157e4b21b8STom Zanussi * 167e4b21b8STom Zanussi * You should have received a copy of the GNU General Public License 177e4b21b8STom Zanussi * along with this program; if not, write to the Free Software 187e4b21b8STom Zanussi * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 197e4b21b8STom Zanussi * 207e4b21b8STom Zanussi */ 217e4b21b8STom Zanussi 227e4b21b8STom Zanussi #include <Python.h> 237e4b21b8STom Zanussi 24fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 257e4b21b8STom Zanussi #include <stdio.h> 267e4b21b8STom Zanussi #include <stdlib.h> 277e4b21b8STom Zanussi #include <string.h> 28df919b40SAdrian Hunter #include <stdbool.h> 297e4b21b8STom Zanussi #include <errno.h> 30adf5bcf3SJiri Olsa #include <linux/bitmap.h> 316c346643SArnaldo Carvalho de Melo #include <linux/compiler.h> 32bd48c63eSArnaldo Carvalho de Melo #include <linux/time64.h> 337e4b21b8STom Zanussi 347e4b21b8STom Zanussi #include "../../perf.h" 3584f5d36fSJiri Olsa #include "../debug.h" 368f651eaeSArnaldo Carvalho de Melo #include "../callchain.h" 37fcf65bf1SArnaldo Carvalho de Melo #include "../evsel.h" 387e4b21b8STom Zanussi #include "../util.h" 39743eb868SArnaldo Carvalho de Melo #include "../event.h" 40743eb868SArnaldo Carvalho de Melo #include "../thread.h" 41df919b40SAdrian Hunter #include "../comm.h" 42df919b40SAdrian Hunter #include "../machine.h" 43df919b40SAdrian Hunter #include "../db-export.h" 446a70307dSAdrian Hunter #include "../thread-stack.h" 457e4b21b8STom Zanussi #include "../trace-event.h" 46451db126SChris Phlipot #include "../call-path.h" 47aef90263SJiri Olsa #include "thread_map.h" 48aef90263SJiri Olsa #include "cpumap.h" 49fea01392SArnaldo Carvalho de Melo #include "print_binary.h" 50aef90263SJiri Olsa #include "stat.h" 5148a1f565SJin Yao #include "mem-events.h" 527e4b21b8STom Zanussi 5366dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3 5466dfdff0SJaroslav Škarvada #define _PyUnicode_FromString(arg) \ 5566dfdff0SJaroslav Škarvada PyString_FromString(arg) 5666dfdff0SJaroslav Škarvada #define _PyUnicode_FromStringAndSize(arg1, arg2) \ 5766dfdff0SJaroslav Škarvada PyString_FromStringAndSize((arg1), (arg2)) 5866dfdff0SJaroslav Škarvada #define _PyBytes_FromStringAndSize(arg1, arg2) \ 5966dfdff0SJaroslav Škarvada PyString_FromStringAndSize((arg1), (arg2)) 6066dfdff0SJaroslav Škarvada #define _PyLong_FromLong(arg) \ 6166dfdff0SJaroslav Škarvada PyInt_FromLong(arg) 6266dfdff0SJaroslav Škarvada #define _PyLong_AsLong(arg) \ 6366dfdff0SJaroslav Škarvada PyInt_AsLong(arg) 6466dfdff0SJaroslav Škarvada #define _PyCapsule_New(arg1, arg2, arg3) \ 6566dfdff0SJaroslav Škarvada PyCObject_FromVoidPtr((arg1), (arg2)) 6666dfdff0SJaroslav Škarvada 677e4b21b8STom Zanussi PyMODINIT_FUNC initperf_trace_context(void); 6866dfdff0SJaroslav Škarvada #else 6966dfdff0SJaroslav Škarvada #define _PyUnicode_FromString(arg) \ 7066dfdff0SJaroslav Škarvada PyUnicode_FromString(arg) 7166dfdff0SJaroslav Škarvada #define _PyUnicode_FromStringAndSize(arg1, arg2) \ 7266dfdff0SJaroslav Škarvada PyUnicode_FromStringAndSize((arg1), (arg2)) 7366dfdff0SJaroslav Škarvada #define _PyBytes_FromStringAndSize(arg1, arg2) \ 7466dfdff0SJaroslav Škarvada PyBytes_FromStringAndSize((arg1), (arg2)) 7566dfdff0SJaroslav Škarvada #define _PyLong_FromLong(arg) \ 7666dfdff0SJaroslav Škarvada PyLong_FromLong(arg) 7766dfdff0SJaroslav Škarvada #define _PyLong_AsLong(arg) \ 7866dfdff0SJaroslav Škarvada PyLong_AsLong(arg) 7966dfdff0SJaroslav Škarvada #define _PyCapsule_New(arg1, arg2, arg3) \ 8066dfdff0SJaroslav Škarvada PyCapsule_New((arg1), (arg2), (arg3)) 8166dfdff0SJaroslav Škarvada 8266dfdff0SJaroslav Škarvada PyMODINIT_FUNC PyInit_perf_trace_context(void); 8366dfdff0SJaroslav Škarvada #endif 847e4b21b8STom Zanussi 85609a7404SSteven Rostedt (Red Hat) #define TRACE_EVENT_TYPE_MAX \ 867e4b21b8STom Zanussi ((1 << (sizeof(unsigned short) * 8)) - 1) 877e4b21b8STom Zanussi 88609a7404SSteven Rostedt (Red Hat) static DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX); 897e4b21b8STom Zanussi 907e4b21b8STom Zanussi #define MAX_FIELDS 64 917e4b21b8STom Zanussi #define N_COMMON_FIELDS 7 927e4b21b8STom Zanussi 937e4b21b8STom Zanussi extern struct scripting_context *scripting_context; 947e4b21b8STom Zanussi 957e4b21b8STom Zanussi static char *cur_field_name; 967e4b21b8STom Zanussi static int zero_flag_atom; 977e4b21b8STom Zanussi 987e4b21b8STom Zanussi static PyObject *main_module, *main_dict; 997e4b21b8STom Zanussi 100df919b40SAdrian Hunter struct tables { 101df919b40SAdrian Hunter struct db_export dbe; 102df919b40SAdrian Hunter PyObject *evsel_handler; 103df919b40SAdrian Hunter PyObject *machine_handler; 104df919b40SAdrian Hunter PyObject *thread_handler; 105df919b40SAdrian Hunter PyObject *comm_handler; 106df919b40SAdrian Hunter PyObject *comm_thread_handler; 107df919b40SAdrian Hunter PyObject *dso_handler; 108df919b40SAdrian Hunter PyObject *symbol_handler; 109c29414f5SAdrian Hunter PyObject *branch_type_handler; 110df919b40SAdrian Hunter PyObject *sample_handler; 1116a70307dSAdrian Hunter PyObject *call_path_handler; 1126a70307dSAdrian Hunter PyObject *call_return_handler; 113df919b40SAdrian Hunter bool db_export_mode; 114df919b40SAdrian Hunter }; 115df919b40SAdrian Hunter 116df919b40SAdrian Hunter static struct tables tables_global; 117df919b40SAdrian Hunter 1186c346643SArnaldo Carvalho de Melo static void handler_call_die(const char *handler_name) __noreturn; 1197e4b21b8STom Zanussi static void handler_call_die(const char *handler_name) 1207e4b21b8STom Zanussi { 1217e4b21b8STom Zanussi PyErr_Print(); 1227e4b21b8STom Zanussi Py_FatalError("problem in Python trace event handler"); 12305f832e3SJoseph Schuchart // Py_FatalError does not return 12405f832e3SJoseph Schuchart // but we have to make the compiler happy 12505f832e3SJoseph Schuchart abort(); 1267e4b21b8STom Zanussi } 1277e4b21b8STom Zanussi 128c0268e8dSJoseph Schuchart /* 129c0268e8dSJoseph Schuchart * Insert val into into the dictionary and decrement the reference counter. 130c0268e8dSJoseph Schuchart * This is necessary for dictionaries since PyDict_SetItemString() does not 131c0268e8dSJoseph Schuchart * steal a reference, as opposed to PyTuple_SetItem(). 132c0268e8dSJoseph Schuchart */ 133c0268e8dSJoseph Schuchart static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val) 134c0268e8dSJoseph Schuchart { 135c0268e8dSJoseph Schuchart PyDict_SetItemString(dict, key, val); 136c0268e8dSJoseph Schuchart Py_DECREF(val); 137c0268e8dSJoseph Schuchart } 138c0268e8dSJoseph Schuchart 139a5563edfSAdrian Hunter static PyObject *get_handler(const char *handler_name) 140a5563edfSAdrian Hunter { 141a5563edfSAdrian Hunter PyObject *handler; 142a5563edfSAdrian Hunter 143a5563edfSAdrian Hunter handler = PyDict_GetItemString(main_dict, handler_name); 144a5563edfSAdrian Hunter if (handler && !PyCallable_Check(handler)) 145a5563edfSAdrian Hunter return NULL; 146a5563edfSAdrian Hunter return handler; 147a5563edfSAdrian Hunter } 148a5563edfSAdrian Hunter 149f38d2816SArun Kalyanasundaram static int get_argument_count(PyObject *handler) 150f38d2816SArun Kalyanasundaram { 151f38d2816SArun Kalyanasundaram int arg_count = 0; 152f38d2816SArun Kalyanasundaram 153f38d2816SArun Kalyanasundaram /* 154f38d2816SArun Kalyanasundaram * The attribute for the code object is func_code in Python 2, 155f38d2816SArun Kalyanasundaram * whereas it is __code__ in Python 3.0+. 156f38d2816SArun Kalyanasundaram */ 157f38d2816SArun Kalyanasundaram PyObject *code_obj = PyObject_GetAttrString(handler, 158f38d2816SArun Kalyanasundaram "func_code"); 159f38d2816SArun Kalyanasundaram if (PyErr_Occurred()) { 160f38d2816SArun Kalyanasundaram PyErr_Clear(); 161f38d2816SArun Kalyanasundaram code_obj = PyObject_GetAttrString(handler, 162f38d2816SArun Kalyanasundaram "__code__"); 163f38d2816SArun Kalyanasundaram } 164f38d2816SArun Kalyanasundaram PyErr_Clear(); 165f38d2816SArun Kalyanasundaram if (code_obj) { 166f38d2816SArun Kalyanasundaram PyObject *arg_count_obj = PyObject_GetAttrString(code_obj, 167f38d2816SArun Kalyanasundaram "co_argcount"); 168f38d2816SArun Kalyanasundaram if (arg_count_obj) { 16966dfdff0SJaroslav Škarvada arg_count = (int) _PyLong_AsLong(arg_count_obj); 170f38d2816SArun Kalyanasundaram Py_DECREF(arg_count_obj); 171f38d2816SArun Kalyanasundaram } 172f38d2816SArun Kalyanasundaram Py_DECREF(code_obj); 173f38d2816SArun Kalyanasundaram } 174f38d2816SArun Kalyanasundaram return arg_count; 175f38d2816SArun Kalyanasundaram } 176f38d2816SArun Kalyanasundaram 177a5563edfSAdrian Hunter static void call_object(PyObject *handler, PyObject *args, const char *die_msg) 178a5563edfSAdrian Hunter { 179a5563edfSAdrian Hunter PyObject *retval; 180a5563edfSAdrian Hunter 181a5563edfSAdrian Hunter retval = PyObject_CallObject(handler, args); 182a5563edfSAdrian Hunter if (retval == NULL) 183a5563edfSAdrian Hunter handler_call_die(die_msg); 184a5563edfSAdrian Hunter Py_DECREF(retval); 185a5563edfSAdrian Hunter } 186a5563edfSAdrian Hunter 187a5563edfSAdrian Hunter static void try_call_object(const char *handler_name, PyObject *args) 188a5563edfSAdrian Hunter { 189a5563edfSAdrian Hunter PyObject *handler; 190a5563edfSAdrian Hunter 191a5563edfSAdrian Hunter handler = get_handler(handler_name); 192a5563edfSAdrian Hunter if (handler) 193a5563edfSAdrian Hunter call_object(handler, args, handler_name); 194a5563edfSAdrian Hunter } 195a5563edfSAdrian Hunter 1967e4b21b8STom Zanussi static void define_value(enum print_arg_type field_type, 1977e4b21b8STom Zanussi const char *ev_name, 1987e4b21b8STom Zanussi const char *field_name, 1997e4b21b8STom Zanussi const char *field_value, 2007e4b21b8STom Zanussi const char *field_str) 2017e4b21b8STom Zanussi { 2027e4b21b8STom Zanussi const char *handler_name = "define_flag_value"; 203a5563edfSAdrian Hunter PyObject *t; 2047e4b21b8STom Zanussi unsigned long long value; 2057e4b21b8STom Zanussi unsigned n = 0; 2067e4b21b8STom Zanussi 2077e4b21b8STom Zanussi if (field_type == PRINT_SYMBOL) 2087e4b21b8STom Zanussi handler_name = "define_symbolic_value"; 2097e4b21b8STom Zanussi 21044ad9cd8STom Zanussi t = PyTuple_New(4); 2117e4b21b8STom Zanussi if (!t) 2127e4b21b8STom Zanussi Py_FatalError("couldn't create Python tuple"); 2137e4b21b8STom Zanussi 2147e4b21b8STom Zanussi value = eval_flag(field_value); 2157e4b21b8STom Zanussi 21666dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name)); 21766dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name)); 21866dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(value)); 21966dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_str)); 2207e4b21b8STom Zanussi 221a5563edfSAdrian Hunter try_call_object(handler_name, t); 2227e4b21b8STom Zanussi 2237e4b21b8STom Zanussi Py_DECREF(t); 2247e4b21b8STom Zanussi } 2257e4b21b8STom Zanussi 2267e4b21b8STom Zanussi static void define_values(enum print_arg_type field_type, 2277e4b21b8STom Zanussi struct print_flag_sym *field, 2287e4b21b8STom Zanussi const char *ev_name, 2297e4b21b8STom Zanussi const char *field_name) 2307e4b21b8STom Zanussi { 2317e4b21b8STom Zanussi define_value(field_type, ev_name, field_name, field->value, 2327e4b21b8STom Zanussi field->str); 2337e4b21b8STom Zanussi 2347e4b21b8STom Zanussi if (field->next) 2357e4b21b8STom Zanussi define_values(field_type, field->next, ev_name, field_name); 2367e4b21b8STom Zanussi } 2377e4b21b8STom Zanussi 2387e4b21b8STom Zanussi static void define_field(enum print_arg_type field_type, 2397e4b21b8STom Zanussi const char *ev_name, 2407e4b21b8STom Zanussi const char *field_name, 2417e4b21b8STom Zanussi const char *delim) 2427e4b21b8STom Zanussi { 2437e4b21b8STom Zanussi const char *handler_name = "define_flag_field"; 244a5563edfSAdrian Hunter PyObject *t; 2457e4b21b8STom Zanussi unsigned n = 0; 2467e4b21b8STom Zanussi 2477e4b21b8STom Zanussi if (field_type == PRINT_SYMBOL) 2487e4b21b8STom Zanussi handler_name = "define_symbolic_field"; 2497e4b21b8STom Zanussi 25044ad9cd8STom Zanussi if (field_type == PRINT_FLAGS) 25144ad9cd8STom Zanussi t = PyTuple_New(3); 25244ad9cd8STom Zanussi else 25344ad9cd8STom Zanussi t = PyTuple_New(2); 2547e4b21b8STom Zanussi if (!t) 2557e4b21b8STom Zanussi Py_FatalError("couldn't create Python tuple"); 2567e4b21b8STom Zanussi 25766dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name)); 25866dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name)); 2597e4b21b8STom Zanussi if (field_type == PRINT_FLAGS) 26066dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(delim)); 2617e4b21b8STom Zanussi 262a5563edfSAdrian Hunter try_call_object(handler_name, t); 2637e4b21b8STom Zanussi 2647e4b21b8STom Zanussi Py_DECREF(t); 2657e4b21b8STom Zanussi } 2667e4b21b8STom Zanussi 2674963b0f8STzvetomir Stoyanov (VMware) static void define_event_symbols(struct tep_event_format *event, 2687e4b21b8STom Zanussi const char *ev_name, 2697e4b21b8STom Zanussi struct print_arg *args) 2707e4b21b8STom Zanussi { 2718579aca3STaeung Song if (args == NULL) 2728579aca3STaeung Song return; 2738579aca3STaeung Song 2747e4b21b8STom Zanussi switch (args->type) { 2757e4b21b8STom Zanussi case PRINT_NULL: 2767e4b21b8STom Zanussi break; 2777e4b21b8STom Zanussi case PRINT_ATOM: 2787e4b21b8STom Zanussi define_value(PRINT_FLAGS, ev_name, cur_field_name, "0", 2797e4b21b8STom Zanussi args->atom.atom); 2807e4b21b8STom Zanussi zero_flag_atom = 0; 2817e4b21b8STom Zanussi break; 2827e4b21b8STom Zanussi case PRINT_FIELD: 2837e4b21b8STom Zanussi free(cur_field_name); 2847e4b21b8STom Zanussi cur_field_name = strdup(args->field.name); 2857e4b21b8STom Zanussi break; 2867e4b21b8STom Zanussi case PRINT_FLAGS: 2877e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->flags.field); 2887e4b21b8STom Zanussi define_field(PRINT_FLAGS, ev_name, cur_field_name, 2897e4b21b8STom Zanussi args->flags.delim); 2907e4b21b8STom Zanussi define_values(PRINT_FLAGS, args->flags.flags, ev_name, 2917e4b21b8STom Zanussi cur_field_name); 2927e4b21b8STom Zanussi break; 2937e4b21b8STom Zanussi case PRINT_SYMBOL: 2947e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->symbol.field); 2957e4b21b8STom Zanussi define_field(PRINT_SYMBOL, ev_name, cur_field_name, NULL); 2967e4b21b8STom Zanussi define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 2977e4b21b8STom Zanussi cur_field_name); 2987e4b21b8STom Zanussi break; 299e080e6f1SNamhyung Kim case PRINT_HEX: 3000fe05591SDaniel Borkmann case PRINT_HEX_STR: 301e080e6f1SNamhyung Kim define_event_symbols(event, ev_name, args->hex.field); 302e080e6f1SNamhyung Kim define_event_symbols(event, ev_name, args->hex.size); 303e080e6f1SNamhyung Kim break; 304b839e1e8SJavi Merino case PRINT_INT_ARRAY: 305b839e1e8SJavi Merino define_event_symbols(event, ev_name, args->int_array.field); 306b839e1e8SJavi Merino define_event_symbols(event, ev_name, args->int_array.count); 307b839e1e8SJavi Merino define_event_symbols(event, ev_name, args->int_array.el_size); 308b839e1e8SJavi Merino break; 3097e4b21b8STom Zanussi case PRINT_STRING: 3107e4b21b8STom Zanussi break; 3117e4b21b8STom Zanussi case PRINT_TYPE: 3127e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->typecast.item); 3137e4b21b8STom Zanussi break; 3147e4b21b8STom Zanussi case PRINT_OP: 3157e4b21b8STom Zanussi if (strcmp(args->op.op, ":") == 0) 3167e4b21b8STom Zanussi zero_flag_atom = 1; 3177e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->op.left); 3187e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->op.right); 3197e4b21b8STom Zanussi break; 3207e4b21b8STom Zanussi default: 321aaf045f7SSteven Rostedt /* gcc warns for these? */ 322aaf045f7SSteven Rostedt case PRINT_BSTRING: 323aaf045f7SSteven Rostedt case PRINT_DYNAMIC_ARRAY: 32476055940SHe Kuang case PRINT_DYNAMIC_ARRAY_LEN: 325aaf045f7SSteven Rostedt case PRINT_FUNC: 326473a778aSSteven Rostedt (Red Hat) case PRINT_BITMASK: 3277e4b21b8STom Zanussi /* we should warn... */ 3287e4b21b8STom Zanussi return; 3297e4b21b8STom Zanussi } 3307e4b21b8STom Zanussi 3317e4b21b8STom Zanussi if (args->next) 3327e4b21b8STom Zanussi define_event_symbols(event, ev_name, args->next); 3337e4b21b8STom Zanussi } 3347e4b21b8STom Zanussi 3354963b0f8STzvetomir Stoyanov (VMware) static PyObject *get_field_numeric_entry(struct tep_event_format *event, 3362c92f982STzvetomir Stoyanov (VMware) struct tep_format_field *field, void *data) 33733058b94SSebastian Andrzej Siewior { 338*bb39ccb2STzvetomir Stoyanov (VMware) bool is_array = field->flags & TEP_FIELD_IS_ARRAY; 33939f54862SArnaldo Carvalho de Melo PyObject *obj = NULL, *list = NULL; 34033058b94SSebastian Andrzej Siewior unsigned long long val; 3418ac631cdSSebastian Andrzej Siewior unsigned int item_size, n_items, i; 34233058b94SSebastian Andrzej Siewior 3438ac631cdSSebastian Andrzej Siewior if (is_array) { 3448ac631cdSSebastian Andrzej Siewior list = PyList_New(field->arraylen); 3458ac631cdSSebastian Andrzej Siewior item_size = field->size / field->arraylen; 3468ac631cdSSebastian Andrzej Siewior n_items = field->arraylen; 3478ac631cdSSebastian Andrzej Siewior } else { 3488ac631cdSSebastian Andrzej Siewior item_size = field->size; 3498ac631cdSSebastian Andrzej Siewior n_items = 1; 3508ac631cdSSebastian Andrzej Siewior } 3518ac631cdSSebastian Andrzej Siewior 3528ac631cdSSebastian Andrzej Siewior for (i = 0; i < n_items; i++) { 3538ac631cdSSebastian Andrzej Siewior 3548ac631cdSSebastian Andrzej Siewior val = read_size(event, data + field->offset + i * item_size, 3558ac631cdSSebastian Andrzej Siewior item_size); 356*bb39ccb2STzvetomir Stoyanov (VMware) if (field->flags & TEP_FIELD_IS_SIGNED) { 35733058b94SSebastian Andrzej Siewior if ((long long)val >= LONG_MIN && 35833058b94SSebastian Andrzej Siewior (long long)val <= LONG_MAX) 35966dfdff0SJaroslav Škarvada obj = _PyLong_FromLong(val); 36033058b94SSebastian Andrzej Siewior else 36133058b94SSebastian Andrzej Siewior obj = PyLong_FromLongLong(val); 36233058b94SSebastian Andrzej Siewior } else { 36333058b94SSebastian Andrzej Siewior if (val <= LONG_MAX) 36466dfdff0SJaroslav Škarvada obj = _PyLong_FromLong(val); 36533058b94SSebastian Andrzej Siewior else 36633058b94SSebastian Andrzej Siewior obj = PyLong_FromUnsignedLongLong(val); 36733058b94SSebastian Andrzej Siewior } 3688ac631cdSSebastian Andrzej Siewior if (is_array) 3698ac631cdSSebastian Andrzej Siewior PyList_SET_ITEM(list, i, obj); 3708ac631cdSSebastian Andrzej Siewior } 3718ac631cdSSebastian Andrzej Siewior if (is_array) 3728ac631cdSSebastian Andrzej Siewior obj = list; 37333058b94SSebastian Andrzej Siewior return obj; 37433058b94SSebastian Andrzej Siewior } 37533058b94SSebastian Andrzej Siewior 3765f9e0f31SJin Yao static const char *get_dsoname(struct map *map) 3775f9e0f31SJin Yao { 3785f9e0f31SJin Yao const char *dsoname = "[unknown]"; 3795f9e0f31SJin Yao 3805f9e0f31SJin Yao if (map && map->dso) { 3815f9e0f31SJin Yao if (symbol_conf.show_kernel_path && map->dso->long_name) 3825f9e0f31SJin Yao dsoname = map->dso->long_name; 3835f9e0f31SJin Yao else 3845f9e0f31SJin Yao dsoname = map->dso->name; 3855f9e0f31SJin Yao } 3865f9e0f31SJin Yao 3875f9e0f31SJin Yao return dsoname; 3885f9e0f31SJin Yao } 3890f5f5bcdSJoseph Schuchart 3900f5f5bcdSJoseph Schuchart static PyObject *python_process_callchain(struct perf_sample *sample, 3910f5f5bcdSJoseph Schuchart struct perf_evsel *evsel, 3920f5f5bcdSJoseph Schuchart struct addr_location *al) 3930f5f5bcdSJoseph Schuchart { 3940f5f5bcdSJoseph Schuchart PyObject *pylist; 3950f5f5bcdSJoseph Schuchart 3960f5f5bcdSJoseph Schuchart pylist = PyList_New(0); 3970f5f5bcdSJoseph Schuchart if (!pylist) 3980f5f5bcdSJoseph Schuchart Py_FatalError("couldn't create Python list"); 3990f5f5bcdSJoseph Schuchart 4000f5f5bcdSJoseph Schuchart if (!symbol_conf.use_callchain || !sample->callchain) 4010f5f5bcdSJoseph Schuchart goto exit; 4020f5f5bcdSJoseph Schuchart 40391d7b2deSArnaldo Carvalho de Melo if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 4040f5f5bcdSJoseph Schuchart sample, NULL, NULL, 40544cbe729SAdrian Hunter scripting_max_stack) != 0) { 4060f5f5bcdSJoseph Schuchart pr_err("Failed to resolve callchain. Skipping\n"); 4070f5f5bcdSJoseph Schuchart goto exit; 4080f5f5bcdSJoseph Schuchart } 4090f5f5bcdSJoseph Schuchart callchain_cursor_commit(&callchain_cursor); 4100f5f5bcdSJoseph Schuchart 4110f5f5bcdSJoseph Schuchart 4120f5f5bcdSJoseph Schuchart while (1) { 4130f5f5bcdSJoseph Schuchart PyObject *pyelem; 4140f5f5bcdSJoseph Schuchart struct callchain_cursor_node *node; 4150f5f5bcdSJoseph Schuchart node = callchain_cursor_current(&callchain_cursor); 4160f5f5bcdSJoseph Schuchart if (!node) 4170f5f5bcdSJoseph Schuchart break; 4180f5f5bcdSJoseph Schuchart 4190f5f5bcdSJoseph Schuchart pyelem = PyDict_New(); 4200f5f5bcdSJoseph Schuchart if (!pyelem) 4210f5f5bcdSJoseph Schuchart Py_FatalError("couldn't create Python dictionary"); 4220f5f5bcdSJoseph Schuchart 4230f5f5bcdSJoseph Schuchart 4240f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pyelem, "ip", 4250f5f5bcdSJoseph Schuchart PyLong_FromUnsignedLongLong(node->ip)); 4260f5f5bcdSJoseph Schuchart 4270f5f5bcdSJoseph Schuchart if (node->sym) { 4280f5f5bcdSJoseph Schuchart PyObject *pysym = PyDict_New(); 4290f5f5bcdSJoseph Schuchart if (!pysym) 4300f5f5bcdSJoseph Schuchart Py_FatalError("couldn't create Python dictionary"); 4310f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pysym, "start", 4320f5f5bcdSJoseph Schuchart PyLong_FromUnsignedLongLong(node->sym->start)); 4330f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pysym, "end", 4340f5f5bcdSJoseph Schuchart PyLong_FromUnsignedLongLong(node->sym->end)); 4350f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pysym, "binding", 43666dfdff0SJaroslav Škarvada _PyLong_FromLong(node->sym->binding)); 4370f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pysym, "name", 43866dfdff0SJaroslav Škarvada _PyUnicode_FromStringAndSize(node->sym->name, 4390f5f5bcdSJoseph Schuchart node->sym->namelen)); 4400f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pyelem, "sym", pysym); 4410f5f5bcdSJoseph Schuchart } 4420f5f5bcdSJoseph Schuchart 4430f5f5bcdSJoseph Schuchart if (node->map) { 4445f9e0f31SJin Yao const char *dsoname = get_dsoname(node->map); 4455f9e0f31SJin Yao 4460f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(pyelem, "dso", 44766dfdff0SJaroslav Škarvada _PyUnicode_FromString(dsoname)); 4480f5f5bcdSJoseph Schuchart } 4490f5f5bcdSJoseph Schuchart 4500f5f5bcdSJoseph Schuchart callchain_cursor_advance(&callchain_cursor); 4510f5f5bcdSJoseph Schuchart PyList_Append(pylist, pyelem); 4520f5f5bcdSJoseph Schuchart Py_DECREF(pyelem); 4530f5f5bcdSJoseph Schuchart } 4540f5f5bcdSJoseph Schuchart 4550f5f5bcdSJoseph Schuchart exit: 4560f5f5bcdSJoseph Schuchart return pylist; 4570f5f5bcdSJoseph Schuchart } 4580f5f5bcdSJoseph Schuchart 45948a1f565SJin Yao static PyObject *python_process_brstack(struct perf_sample *sample, 46048a1f565SJin Yao struct thread *thread) 46148a1f565SJin Yao { 46248a1f565SJin Yao struct branch_stack *br = sample->branch_stack; 46348a1f565SJin Yao PyObject *pylist; 46448a1f565SJin Yao u64 i; 46548a1f565SJin Yao 46648a1f565SJin Yao pylist = PyList_New(0); 46748a1f565SJin Yao if (!pylist) 46848a1f565SJin Yao Py_FatalError("couldn't create Python list"); 46948a1f565SJin Yao 47048a1f565SJin Yao if (!(br && br->nr)) 47148a1f565SJin Yao goto exit; 47248a1f565SJin Yao 47348a1f565SJin Yao for (i = 0; i < br->nr; i++) { 47448a1f565SJin Yao PyObject *pyelem; 47548a1f565SJin Yao struct addr_location al; 47648a1f565SJin Yao const char *dsoname; 47748a1f565SJin Yao 47848a1f565SJin Yao pyelem = PyDict_New(); 47948a1f565SJin Yao if (!pyelem) 48048a1f565SJin Yao Py_FatalError("couldn't create Python dictionary"); 48148a1f565SJin Yao 48248a1f565SJin Yao pydict_set_item_string_decref(pyelem, "from", 48348a1f565SJin Yao PyLong_FromUnsignedLongLong(br->entries[i].from)); 48448a1f565SJin Yao pydict_set_item_string_decref(pyelem, "to", 48548a1f565SJin Yao PyLong_FromUnsignedLongLong(br->entries[i].to)); 48648a1f565SJin Yao pydict_set_item_string_decref(pyelem, "mispred", 48748a1f565SJin Yao PyBool_FromLong(br->entries[i].flags.mispred)); 48848a1f565SJin Yao pydict_set_item_string_decref(pyelem, "predicted", 48948a1f565SJin Yao PyBool_FromLong(br->entries[i].flags.predicted)); 49048a1f565SJin Yao pydict_set_item_string_decref(pyelem, "in_tx", 49148a1f565SJin Yao PyBool_FromLong(br->entries[i].flags.in_tx)); 49248a1f565SJin Yao pydict_set_item_string_decref(pyelem, "abort", 49348a1f565SJin Yao PyBool_FromLong(br->entries[i].flags.abort)); 49448a1f565SJin Yao pydict_set_item_string_decref(pyelem, "cycles", 49548a1f565SJin Yao PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles)); 49648a1f565SJin Yao 49748a1f565SJin Yao thread__find_map(thread, sample->cpumode, 49848a1f565SJin Yao br->entries[i].from, &al); 49948a1f565SJin Yao dsoname = get_dsoname(al.map); 50048a1f565SJin Yao pydict_set_item_string_decref(pyelem, "from_dsoname", 50148a1f565SJin Yao _PyUnicode_FromString(dsoname)); 50248a1f565SJin Yao 50348a1f565SJin Yao thread__find_map(thread, sample->cpumode, 50448a1f565SJin Yao br->entries[i].to, &al); 50548a1f565SJin Yao dsoname = get_dsoname(al.map); 50648a1f565SJin Yao pydict_set_item_string_decref(pyelem, "to_dsoname", 50748a1f565SJin Yao _PyUnicode_FromString(dsoname)); 50848a1f565SJin Yao 50948a1f565SJin Yao PyList_Append(pylist, pyelem); 51048a1f565SJin Yao Py_DECREF(pyelem); 51148a1f565SJin Yao } 51248a1f565SJin Yao 51348a1f565SJin Yao exit: 51448a1f565SJin Yao return pylist; 51548a1f565SJin Yao } 51648a1f565SJin Yao 51748a1f565SJin Yao static unsigned long get_offset(struct symbol *sym, struct addr_location *al) 51848a1f565SJin Yao { 51948a1f565SJin Yao unsigned long offset; 52048a1f565SJin Yao 52148a1f565SJin Yao if (al->addr < sym->end) 52248a1f565SJin Yao offset = al->addr - sym->start; 52348a1f565SJin Yao else 52448a1f565SJin Yao offset = al->addr - al->map->start - sym->start; 52548a1f565SJin Yao 52648a1f565SJin Yao return offset; 52748a1f565SJin Yao } 52848a1f565SJin Yao 52948a1f565SJin Yao static int get_symoff(struct symbol *sym, struct addr_location *al, 53048a1f565SJin Yao bool print_off, char *bf, int size) 53148a1f565SJin Yao { 53248a1f565SJin Yao unsigned long offset; 53348a1f565SJin Yao 53448a1f565SJin Yao if (!sym || !sym->name[0]) 53548a1f565SJin Yao return scnprintf(bf, size, "%s", "[unknown]"); 53648a1f565SJin Yao 53748a1f565SJin Yao if (!print_off) 53848a1f565SJin Yao return scnprintf(bf, size, "%s", sym->name); 53948a1f565SJin Yao 54048a1f565SJin Yao offset = get_offset(sym, al); 54148a1f565SJin Yao 54248a1f565SJin Yao return scnprintf(bf, size, "%s+0x%x", sym->name, offset); 54348a1f565SJin Yao } 54448a1f565SJin Yao 54548a1f565SJin Yao static int get_br_mspred(struct branch_flags *flags, char *bf, int size) 54648a1f565SJin Yao { 54748a1f565SJin Yao if (!flags->mispred && !flags->predicted) 54848a1f565SJin Yao return scnprintf(bf, size, "%s", "-"); 54948a1f565SJin Yao 55048a1f565SJin Yao if (flags->mispred) 55148a1f565SJin Yao return scnprintf(bf, size, "%s", "M"); 55248a1f565SJin Yao 55348a1f565SJin Yao return scnprintf(bf, size, "%s", "P"); 55448a1f565SJin Yao } 55548a1f565SJin Yao 55648a1f565SJin Yao static PyObject *python_process_brstacksym(struct perf_sample *sample, 55748a1f565SJin Yao struct thread *thread) 55848a1f565SJin Yao { 55948a1f565SJin Yao struct branch_stack *br = sample->branch_stack; 56048a1f565SJin Yao PyObject *pylist; 56148a1f565SJin Yao u64 i; 56248a1f565SJin Yao char bf[512]; 56348a1f565SJin Yao struct addr_location al; 56448a1f565SJin Yao 56548a1f565SJin Yao pylist = PyList_New(0); 56648a1f565SJin Yao if (!pylist) 56748a1f565SJin Yao Py_FatalError("couldn't create Python list"); 56848a1f565SJin Yao 56948a1f565SJin Yao if (!(br && br->nr)) 57048a1f565SJin Yao goto exit; 57148a1f565SJin Yao 57248a1f565SJin Yao for (i = 0; i < br->nr; i++) { 57348a1f565SJin Yao PyObject *pyelem; 57448a1f565SJin Yao 57548a1f565SJin Yao pyelem = PyDict_New(); 57648a1f565SJin Yao if (!pyelem) 57748a1f565SJin Yao Py_FatalError("couldn't create Python dictionary"); 57848a1f565SJin Yao 57948a1f565SJin Yao thread__find_symbol(thread, sample->cpumode, 58048a1f565SJin Yao br->entries[i].from, &al); 58148a1f565SJin Yao get_symoff(al.sym, &al, true, bf, sizeof(bf)); 58248a1f565SJin Yao pydict_set_item_string_decref(pyelem, "from", 58348a1f565SJin Yao _PyUnicode_FromString(bf)); 58448a1f565SJin Yao 58548a1f565SJin Yao thread__find_symbol(thread, sample->cpumode, 58648a1f565SJin Yao br->entries[i].to, &al); 58748a1f565SJin Yao get_symoff(al.sym, &al, true, bf, sizeof(bf)); 58848a1f565SJin Yao pydict_set_item_string_decref(pyelem, "to", 58948a1f565SJin Yao _PyUnicode_FromString(bf)); 59048a1f565SJin Yao 59148a1f565SJin Yao get_br_mspred(&br->entries[i].flags, bf, sizeof(bf)); 59248a1f565SJin Yao pydict_set_item_string_decref(pyelem, "pred", 59348a1f565SJin Yao _PyUnicode_FromString(bf)); 59448a1f565SJin Yao 59548a1f565SJin Yao if (br->entries[i].flags.in_tx) { 59648a1f565SJin Yao pydict_set_item_string_decref(pyelem, "in_tx", 59748a1f565SJin Yao _PyUnicode_FromString("X")); 59848a1f565SJin Yao } else { 59948a1f565SJin Yao pydict_set_item_string_decref(pyelem, "in_tx", 60048a1f565SJin Yao _PyUnicode_FromString("-")); 60148a1f565SJin Yao } 60248a1f565SJin Yao 60348a1f565SJin Yao if (br->entries[i].flags.abort) { 60448a1f565SJin Yao pydict_set_item_string_decref(pyelem, "abort", 60548a1f565SJin Yao _PyUnicode_FromString("A")); 60648a1f565SJin Yao } else { 60748a1f565SJin Yao pydict_set_item_string_decref(pyelem, "abort", 60848a1f565SJin Yao _PyUnicode_FromString("-")); 60948a1f565SJin Yao } 61048a1f565SJin Yao 61148a1f565SJin Yao PyList_Append(pylist, pyelem); 61248a1f565SJin Yao Py_DECREF(pyelem); 61348a1f565SJin Yao } 61448a1f565SJin Yao 61548a1f565SJin Yao exit: 61648a1f565SJin Yao return pylist; 61748a1f565SJin Yao } 61848a1f565SJin Yao 61974ec14f3SArun Kalyanasundaram static PyObject *get_sample_value_as_tuple(struct sample_read_value *value) 62074ec14f3SArun Kalyanasundaram { 62174ec14f3SArun Kalyanasundaram PyObject *t; 62274ec14f3SArun Kalyanasundaram 62374ec14f3SArun Kalyanasundaram t = PyTuple_New(2); 62474ec14f3SArun Kalyanasundaram if (!t) 62574ec14f3SArun Kalyanasundaram Py_FatalError("couldn't create Python tuple"); 62674ec14f3SArun Kalyanasundaram PyTuple_SetItem(t, 0, PyLong_FromUnsignedLongLong(value->id)); 62774ec14f3SArun Kalyanasundaram PyTuple_SetItem(t, 1, PyLong_FromUnsignedLongLong(value->value)); 62874ec14f3SArun Kalyanasundaram return t; 62974ec14f3SArun Kalyanasundaram } 63074ec14f3SArun Kalyanasundaram 63174ec14f3SArun Kalyanasundaram static void set_sample_read_in_dict(PyObject *dict_sample, 63274ec14f3SArun Kalyanasundaram struct perf_sample *sample, 63374ec14f3SArun Kalyanasundaram struct perf_evsel *evsel) 63474ec14f3SArun Kalyanasundaram { 63574ec14f3SArun Kalyanasundaram u64 read_format = evsel->attr.read_format; 63674ec14f3SArun Kalyanasundaram PyObject *values; 63774ec14f3SArun Kalyanasundaram unsigned int i; 63874ec14f3SArun Kalyanasundaram 63974ec14f3SArun Kalyanasundaram if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { 64074ec14f3SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "time_enabled", 64174ec14f3SArun Kalyanasundaram PyLong_FromUnsignedLongLong(sample->read.time_enabled)); 64274ec14f3SArun Kalyanasundaram } 64374ec14f3SArun Kalyanasundaram 64474ec14f3SArun Kalyanasundaram if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { 64574ec14f3SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "time_running", 64674ec14f3SArun Kalyanasundaram PyLong_FromUnsignedLongLong(sample->read.time_running)); 64774ec14f3SArun Kalyanasundaram } 64874ec14f3SArun Kalyanasundaram 64974ec14f3SArun Kalyanasundaram if (read_format & PERF_FORMAT_GROUP) 65074ec14f3SArun Kalyanasundaram values = PyList_New(sample->read.group.nr); 65174ec14f3SArun Kalyanasundaram else 65274ec14f3SArun Kalyanasundaram values = PyList_New(1); 65374ec14f3SArun Kalyanasundaram 65474ec14f3SArun Kalyanasundaram if (!values) 65574ec14f3SArun Kalyanasundaram Py_FatalError("couldn't create Python list"); 65674ec14f3SArun Kalyanasundaram 65774ec14f3SArun Kalyanasundaram if (read_format & PERF_FORMAT_GROUP) { 65874ec14f3SArun Kalyanasundaram for (i = 0; i < sample->read.group.nr; i++) { 65974ec14f3SArun Kalyanasundaram PyObject *t = get_sample_value_as_tuple(&sample->read.group.values[i]); 66074ec14f3SArun Kalyanasundaram PyList_SET_ITEM(values, i, t); 66174ec14f3SArun Kalyanasundaram } 66274ec14f3SArun Kalyanasundaram } else { 66374ec14f3SArun Kalyanasundaram PyObject *t = get_sample_value_as_tuple(&sample->read.one); 66474ec14f3SArun Kalyanasundaram PyList_SET_ITEM(values, 0, t); 66574ec14f3SArun Kalyanasundaram } 66674ec14f3SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "values", values); 66774ec14f3SArun Kalyanasundaram } 66874ec14f3SArun Kalyanasundaram 66948a1f565SJin Yao static void set_sample_datasrc_in_dict(PyObject *dict, 67048a1f565SJin Yao struct perf_sample *sample) 67148a1f565SJin Yao { 67248a1f565SJin Yao struct mem_info mi = { .data_src.val = sample->data_src }; 67348a1f565SJin Yao char decode[100]; 67448a1f565SJin Yao 67548a1f565SJin Yao pydict_set_item_string_decref(dict, "datasrc", 67648a1f565SJin Yao PyLong_FromUnsignedLongLong(sample->data_src)); 67748a1f565SJin Yao 67848a1f565SJin Yao perf_script__meminfo_scnprintf(decode, 100, &mi); 67948a1f565SJin Yao 68048a1f565SJin Yao pydict_set_item_string_decref(dict, "datasrc_decode", 68148a1f565SJin Yao _PyUnicode_FromString(decode)); 68248a1f565SJin Yao } 68348a1f565SJin Yao 68448a1f565SJin Yao static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) 68548a1f565SJin Yao { 68648a1f565SJin Yao unsigned int i = 0, r; 68748a1f565SJin Yao int printed = 0; 68848a1f565SJin Yao 68948a1f565SJin Yao bf[0] = 0; 69048a1f565SJin Yao 69148a1f565SJin Yao for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 69248a1f565SJin Yao u64 val = regs->regs[i++]; 69348a1f565SJin Yao 69448a1f565SJin Yao printed += scnprintf(bf + printed, size - printed, 69548a1f565SJin Yao "%5s:0x%" PRIx64 " ", 69648a1f565SJin Yao perf_reg_name(r), val); 69748a1f565SJin Yao } 69848a1f565SJin Yao 69948a1f565SJin Yao return printed; 70048a1f565SJin Yao } 70148a1f565SJin Yao 70248a1f565SJin Yao static void set_regs_in_dict(PyObject *dict, 70348a1f565SJin Yao struct perf_sample *sample, 70448a1f565SJin Yao struct perf_evsel *evsel) 70548a1f565SJin Yao { 70648a1f565SJin Yao struct perf_event_attr *attr = &evsel->attr; 70748a1f565SJin Yao char bf[512]; 70848a1f565SJin Yao 70948a1f565SJin Yao regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); 71048a1f565SJin Yao 71148a1f565SJin Yao pydict_set_item_string_decref(dict, "iregs", 71248a1f565SJin Yao _PyUnicode_FromString(bf)); 71348a1f565SJin Yao 71448a1f565SJin Yao regs_map(&sample->user_regs, attr->sample_regs_user, bf, sizeof(bf)); 71548a1f565SJin Yao 71648a1f565SJin Yao pydict_set_item_string_decref(dict, "uregs", 71748a1f565SJin Yao _PyUnicode_FromString(bf)); 71848a1f565SJin Yao } 71948a1f565SJin Yao 720892e76b2SArun Kalyanasundaram static PyObject *get_perf_sample_dict(struct perf_sample *sample, 721892e76b2SArun Kalyanasundaram struct perf_evsel *evsel, 722892e76b2SArun Kalyanasundaram struct addr_location *al, 723892e76b2SArun Kalyanasundaram PyObject *callchain) 724892e76b2SArun Kalyanasundaram { 72548a1f565SJin Yao PyObject *dict, *dict_sample, *brstack, *brstacksym; 726892e76b2SArun Kalyanasundaram 727892e76b2SArun Kalyanasundaram dict = PyDict_New(); 728892e76b2SArun Kalyanasundaram if (!dict) 729892e76b2SArun Kalyanasundaram Py_FatalError("couldn't create Python dictionary"); 730892e76b2SArun Kalyanasundaram 731892e76b2SArun Kalyanasundaram dict_sample = PyDict_New(); 732892e76b2SArun Kalyanasundaram if (!dict_sample) 733892e76b2SArun Kalyanasundaram Py_FatalError("couldn't create Python dictionary"); 734892e76b2SArun Kalyanasundaram 73566dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel))); 73666dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "attr", _PyUnicode_FromStringAndSize( 737892e76b2SArun Kalyanasundaram (const char *)&evsel->attr, sizeof(evsel->attr))); 738892e76b2SArun Kalyanasundaram 739892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "pid", 74066dfdff0SJaroslav Škarvada _PyLong_FromLong(sample->pid)); 741892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "tid", 74266dfdff0SJaroslav Škarvada _PyLong_FromLong(sample->tid)); 743892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "cpu", 74466dfdff0SJaroslav Škarvada _PyLong_FromLong(sample->cpu)); 745892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "ip", 746892e76b2SArun Kalyanasundaram PyLong_FromUnsignedLongLong(sample->ip)); 747892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "time", 748892e76b2SArun Kalyanasundaram PyLong_FromUnsignedLongLong(sample->time)); 749892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict_sample, "period", 750892e76b2SArun Kalyanasundaram PyLong_FromUnsignedLongLong(sample->period)); 75141013f0cSKan Liang pydict_set_item_string_decref(dict_sample, "phys_addr", 75241013f0cSKan Liang PyLong_FromUnsignedLongLong(sample->phys_addr)); 753943f32a0SLeo Yan pydict_set_item_string_decref(dict_sample, "addr", 754943f32a0SLeo Yan PyLong_FromUnsignedLongLong(sample->addr)); 75574ec14f3SArun Kalyanasundaram set_sample_read_in_dict(dict_sample, sample, evsel); 75648a1f565SJin Yao pydict_set_item_string_decref(dict_sample, "weight", 75748a1f565SJin Yao PyLong_FromUnsignedLongLong(sample->weight)); 75848a1f565SJin Yao pydict_set_item_string_decref(dict_sample, "transaction", 75948a1f565SJin Yao PyLong_FromUnsignedLongLong(sample->transaction)); 76048a1f565SJin Yao set_sample_datasrc_in_dict(dict_sample, sample); 761892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict, "sample", dict_sample); 762892e76b2SArun Kalyanasundaram 76366dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "raw_buf", _PyBytes_FromStringAndSize( 764892e76b2SArun Kalyanasundaram (const char *)sample->raw_data, sample->raw_size)); 765892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict, "comm", 76666dfdff0SJaroslav Škarvada _PyUnicode_FromString(thread__comm_str(al->thread))); 767892e76b2SArun Kalyanasundaram if (al->map) { 768892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict, "dso", 76966dfdff0SJaroslav Škarvada _PyUnicode_FromString(al->map->dso->name)); 770892e76b2SArun Kalyanasundaram } 771892e76b2SArun Kalyanasundaram if (al->sym) { 772892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict, "symbol", 77366dfdff0SJaroslav Škarvada _PyUnicode_FromString(al->sym->name)); 774892e76b2SArun Kalyanasundaram } 775892e76b2SArun Kalyanasundaram 776892e76b2SArun Kalyanasundaram pydict_set_item_string_decref(dict, "callchain", callchain); 777892e76b2SArun Kalyanasundaram 77848a1f565SJin Yao brstack = python_process_brstack(sample, al->thread); 77948a1f565SJin Yao pydict_set_item_string_decref(dict, "brstack", brstack); 78048a1f565SJin Yao 78148a1f565SJin Yao brstacksym = python_process_brstacksym(sample, al->thread); 78248a1f565SJin Yao pydict_set_item_string_decref(dict, "brstacksym", brstacksym); 78348a1f565SJin Yao 78448a1f565SJin Yao set_regs_in_dict(dict, sample, evsel); 78548a1f565SJin Yao 786892e76b2SArun Kalyanasundaram return dict; 787892e76b2SArun Kalyanasundaram } 788892e76b2SArun Kalyanasundaram 789b7fff6b5SArnaldo Carvalho de Melo static void python_process_tracepoint(struct perf_sample *sample, 790fcf65bf1SArnaldo Carvalho de Melo struct perf_evsel *evsel, 79173994dc1SFeng Tang struct addr_location *al) 7927e4b21b8STom Zanussi { 7934963b0f8STzvetomir Stoyanov (VMware) struct tep_event_format *event = evsel->tp_format; 79439f54862SArnaldo Carvalho de Melo PyObject *handler, *context, *t, *obj = NULL, *callchain; 795f38d2816SArun Kalyanasundaram PyObject *dict = NULL, *all_entries_dict = NULL; 7967e4b21b8STom Zanussi static char handler_name[256]; 7972c92f982STzvetomir Stoyanov (VMware) struct tep_format_field *field; 7987e4b21b8STom Zanussi unsigned long s, ns; 7997e4b21b8STom Zanussi unsigned n = 0; 8007e4b21b8STom Zanussi int pid; 801be6d842aSDavid Ahern int cpu = sample->cpu; 802be6d842aSDavid Ahern void *data = sample->raw_data; 803be6d842aSDavid Ahern unsigned long long nsecs = sample->time; 804f9d5d549SArnaldo Carvalho de Melo const char *comm = thread__comm_str(al->thread); 805e9f9a9caSArun Kalyanasundaram const char *default_handler_name = "trace_unhandled"; 8067e4b21b8STom Zanussi 80762665dffSArnaldo Carvalho de Melo if (!event) { 80862665dffSArnaldo Carvalho de Melo snprintf(handler_name, sizeof(handler_name), 80962665dffSArnaldo Carvalho de Melo "ug! no event found for type %" PRIu64, (u64)evsel->attr.config); 81062665dffSArnaldo Carvalho de Melo Py_FatalError(handler_name); 81162665dffSArnaldo Carvalho de Melo } 8127e4b21b8STom Zanussi 81397822433SArnaldo Carvalho de Melo pid = raw_field_value(event, "common_pid", data); 8147e4b21b8STom Zanussi 8157e4b21b8STom Zanussi sprintf(handler_name, "%s__%s", event->system, event->name); 8167e4b21b8STom Zanussi 817adf5bcf3SJiri Olsa if (!test_and_set_bit(event->id, events_defined)) 818adf5bcf3SJiri Olsa define_event_symbols(event, handler_name, event->print_fmt.args); 819adf5bcf3SJiri Olsa 820a5563edfSAdrian Hunter handler = get_handler(handler_name); 821c0251485SPierre Tardy if (!handler) { 822e9f9a9caSArun Kalyanasundaram handler = get_handler(default_handler_name); 823e9f9a9caSArun Kalyanasundaram if (!handler) 824e9f9a9caSArun Kalyanasundaram return; 825c0251485SPierre Tardy dict = PyDict_New(); 826c0251485SPierre Tardy if (!dict) 827c0251485SPierre Tardy Py_FatalError("couldn't create Python dict"); 828c0251485SPierre Tardy } 829e9f9a9caSArun Kalyanasundaram 830e9f9a9caSArun Kalyanasundaram t = PyTuple_New(MAX_FIELDS); 831e9f9a9caSArun Kalyanasundaram if (!t) 832e9f9a9caSArun Kalyanasundaram Py_FatalError("couldn't create Python tuple"); 833e9f9a9caSArun Kalyanasundaram 834e9f9a9caSArun Kalyanasundaram 835bd48c63eSArnaldo Carvalho de Melo s = nsecs / NSEC_PER_SEC; 836bd48c63eSArnaldo Carvalho de Melo ns = nsecs - s * NSEC_PER_SEC; 8377e4b21b8STom Zanussi 8387e4b21b8STom Zanussi scripting_context->event_data = data; 8392de9533dSTom Zanussi scripting_context->pevent = evsel->tp_format->pevent; 8407e4b21b8STom Zanussi 84166dfdff0SJaroslav Škarvada context = _PyCapsule_New(scripting_context, NULL, NULL); 8427e4b21b8STom Zanussi 84366dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(handler_name)); 844fb7d0b3cSKyle McMartin PyTuple_SetItem(t, n++, context); 845c0251485SPierre Tardy 8460f5f5bcdSJoseph Schuchart /* ip unwinding */ 8470f5f5bcdSJoseph Schuchart callchain = python_process_callchain(sample, evsel, al); 848f38d2816SArun Kalyanasundaram /* Need an additional reference for the perf_sample dict */ 849f38d2816SArun Kalyanasundaram Py_INCREF(callchain); 8500f5f5bcdSJoseph Schuchart 851e9f9a9caSArun Kalyanasundaram if (!dict) { 85266dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu)); 85366dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(s)); 85466dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(ns)); 85566dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(pid)); 85666dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyUnicode_FromString(comm)); 8570f5f5bcdSJoseph Schuchart PyTuple_SetItem(t, n++, callchain); 858c0251485SPierre Tardy } else { 85966dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "common_cpu", _PyLong_FromLong(cpu)); 86066dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "common_s", _PyLong_FromLong(s)); 86166dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "common_ns", _PyLong_FromLong(ns)); 86266dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "common_pid", _PyLong_FromLong(pid)); 86366dfdff0SJaroslav Škarvada pydict_set_item_string_decref(dict, "common_comm", _PyUnicode_FromString(comm)); 8640f5f5bcdSJoseph Schuchart pydict_set_item_string_decref(dict, "common_callchain", callchain); 865c0251485SPierre Tardy } 8667e4b21b8STom Zanussi for (field = event->format.fields; field; field = field->next) { 867249de6e0SJiri Olsa unsigned int offset, len; 868249de6e0SJiri Olsa unsigned long long val; 869249de6e0SJiri Olsa 870*bb39ccb2STzvetomir Stoyanov (VMware) if (field->flags & TEP_FIELD_IS_ARRAY) { 8717e4b21b8STom Zanussi offset = field->offset; 872249de6e0SJiri Olsa len = field->size; 873*bb39ccb2STzvetomir Stoyanov (VMware) if (field->flags & TEP_FIELD_IS_DYNAMIC) { 87459c1baeeSTzvetomir Stoyanov (VMware) val = tep_read_number(scripting_context->pevent, 875249de6e0SJiri Olsa data + offset, len); 876249de6e0SJiri Olsa offset = val; 877249de6e0SJiri Olsa len = offset >> 16; 878249de6e0SJiri Olsa offset &= 0xffff; 879249de6e0SJiri Olsa } 880*bb39ccb2STzvetomir Stoyanov (VMware) if (field->flags & TEP_FIELD_IS_STRING && 881249de6e0SJiri Olsa is_printable_array(data + offset, len)) { 88266dfdff0SJaroslav Škarvada obj = _PyUnicode_FromString((char *) data + offset); 883249de6e0SJiri Olsa } else { 884249de6e0SJiri Olsa obj = PyByteArray_FromStringAndSize((const char *) data + offset, len); 885*bb39ccb2STzvetomir Stoyanov (VMware) field->flags &= ~TEP_FIELD_IS_STRING; 886249de6e0SJiri Olsa } 8877e4b21b8STom Zanussi } else { /* FIELD_IS_NUMERIC */ 88833058b94SSebastian Andrzej Siewior obj = get_field_numeric_entry(event, field, data); 8897e4b21b8STom Zanussi } 890e9f9a9caSArun Kalyanasundaram if (!dict) 891b1dcc03cSTom Zanussi PyTuple_SetItem(t, n++, obj); 892c0251485SPierre Tardy else 893c0268e8dSJoseph Schuchart pydict_set_item_string_decref(dict, field->name, obj); 894c0251485SPierre Tardy 8957e4b21b8STom Zanussi } 8960f5f5bcdSJoseph Schuchart 897e9f9a9caSArun Kalyanasundaram if (dict) 898c0251485SPierre Tardy PyTuple_SetItem(t, n++, dict); 8997e4b21b8STom Zanussi 900f38d2816SArun Kalyanasundaram if (get_argument_count(handler) == (int) n + 1) { 901f38d2816SArun Kalyanasundaram all_entries_dict = get_perf_sample_dict(sample, evsel, al, 902f38d2816SArun Kalyanasundaram callchain); 903f38d2816SArun Kalyanasundaram PyTuple_SetItem(t, n++, all_entries_dict); 904f38d2816SArun Kalyanasundaram } else { 905f38d2816SArun Kalyanasundaram Py_DECREF(callchain); 906f38d2816SArun Kalyanasundaram } 907f38d2816SArun Kalyanasundaram 9087e4b21b8STom Zanussi if (_PyTuple_Resize(&t, n) == -1) 9097e4b21b8STom Zanussi Py_FatalError("error resizing Python tuple"); 9107e4b21b8STom Zanussi 911db0ba84cSJanne Huttunen if (!dict) 912a5563edfSAdrian Hunter call_object(handler, t, handler_name); 913db0ba84cSJanne Huttunen else 914e9f9a9caSArun Kalyanasundaram call_object(handler, t, default_handler_name); 9157e4b21b8STom Zanussi 9167e4b21b8STom Zanussi Py_DECREF(t); 9177e4b21b8STom Zanussi } 9187e4b21b8STom Zanussi 919df919b40SAdrian Hunter static PyObject *tuple_new(unsigned int sz) 920df919b40SAdrian Hunter { 921df919b40SAdrian Hunter PyObject *t; 922df919b40SAdrian Hunter 923df919b40SAdrian Hunter t = PyTuple_New(sz); 924df919b40SAdrian Hunter if (!t) 925df919b40SAdrian Hunter Py_FatalError("couldn't create Python tuple"); 926df919b40SAdrian Hunter return t; 927df919b40SAdrian Hunter } 928df919b40SAdrian Hunter 929df919b40SAdrian Hunter static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) 930df919b40SAdrian Hunter { 931df919b40SAdrian Hunter #if BITS_PER_LONG == 64 93266dfdff0SJaroslav Škarvada return PyTuple_SetItem(t, pos, _PyLong_FromLong(val)); 933df919b40SAdrian Hunter #endif 934df919b40SAdrian Hunter #if BITS_PER_LONG == 32 935df919b40SAdrian Hunter return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val)); 936df919b40SAdrian Hunter #endif 937df919b40SAdrian Hunter } 938df919b40SAdrian Hunter 939df919b40SAdrian Hunter static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val) 940df919b40SAdrian Hunter { 94166dfdff0SJaroslav Škarvada return PyTuple_SetItem(t, pos, _PyLong_FromLong(val)); 942df919b40SAdrian Hunter } 943df919b40SAdrian Hunter 944df919b40SAdrian Hunter static int tuple_set_string(PyObject *t, unsigned int pos, const char *s) 945df919b40SAdrian Hunter { 94666dfdff0SJaroslav Škarvada return PyTuple_SetItem(t, pos, _PyUnicode_FromString(s)); 947df919b40SAdrian Hunter } 948df919b40SAdrian Hunter 949df919b40SAdrian Hunter static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel) 950df919b40SAdrian Hunter { 951df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 952df919b40SAdrian Hunter PyObject *t; 953df919b40SAdrian Hunter 954df919b40SAdrian Hunter t = tuple_new(2); 955df919b40SAdrian Hunter 956df919b40SAdrian Hunter tuple_set_u64(t, 0, evsel->db_id); 957df919b40SAdrian Hunter tuple_set_string(t, 1, perf_evsel__name(evsel)); 958df919b40SAdrian Hunter 959df919b40SAdrian Hunter call_object(tables->evsel_handler, t, "evsel_table"); 960df919b40SAdrian Hunter 961df919b40SAdrian Hunter Py_DECREF(t); 962df919b40SAdrian Hunter 963df919b40SAdrian Hunter return 0; 964df919b40SAdrian Hunter } 965df919b40SAdrian Hunter 966df919b40SAdrian Hunter static int python_export_machine(struct db_export *dbe, 967df919b40SAdrian Hunter struct machine *machine) 968df919b40SAdrian Hunter { 969df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 970df919b40SAdrian Hunter PyObject *t; 971df919b40SAdrian Hunter 972df919b40SAdrian Hunter t = tuple_new(3); 973df919b40SAdrian Hunter 974df919b40SAdrian Hunter tuple_set_u64(t, 0, machine->db_id); 975df919b40SAdrian Hunter tuple_set_s32(t, 1, machine->pid); 976df919b40SAdrian Hunter tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : ""); 977df919b40SAdrian Hunter 978df919b40SAdrian Hunter call_object(tables->machine_handler, t, "machine_table"); 979df919b40SAdrian Hunter 980df919b40SAdrian Hunter Py_DECREF(t); 981df919b40SAdrian Hunter 982df919b40SAdrian Hunter return 0; 983df919b40SAdrian Hunter } 984df919b40SAdrian Hunter 985df919b40SAdrian Hunter static int python_export_thread(struct db_export *dbe, struct thread *thread, 986df919b40SAdrian Hunter u64 main_thread_db_id, struct machine *machine) 987df919b40SAdrian Hunter { 988df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 989df919b40SAdrian Hunter PyObject *t; 990df919b40SAdrian Hunter 991df919b40SAdrian Hunter t = tuple_new(5); 992df919b40SAdrian Hunter 993df919b40SAdrian Hunter tuple_set_u64(t, 0, thread->db_id); 994df919b40SAdrian Hunter tuple_set_u64(t, 1, machine->db_id); 995df919b40SAdrian Hunter tuple_set_u64(t, 2, main_thread_db_id); 996df919b40SAdrian Hunter tuple_set_s32(t, 3, thread->pid_); 997df919b40SAdrian Hunter tuple_set_s32(t, 4, thread->tid); 998df919b40SAdrian Hunter 999df919b40SAdrian Hunter call_object(tables->thread_handler, t, "thread_table"); 1000df919b40SAdrian Hunter 1001df919b40SAdrian Hunter Py_DECREF(t); 1002df919b40SAdrian Hunter 1003df919b40SAdrian Hunter return 0; 1004df919b40SAdrian Hunter } 1005df919b40SAdrian Hunter 1006df919b40SAdrian Hunter static int python_export_comm(struct db_export *dbe, struct comm *comm) 1007df919b40SAdrian Hunter { 1008df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1009df919b40SAdrian Hunter PyObject *t; 1010df919b40SAdrian Hunter 1011df919b40SAdrian Hunter t = tuple_new(2); 1012df919b40SAdrian Hunter 1013df919b40SAdrian Hunter tuple_set_u64(t, 0, comm->db_id); 1014df919b40SAdrian Hunter tuple_set_string(t, 1, comm__str(comm)); 1015df919b40SAdrian Hunter 1016df919b40SAdrian Hunter call_object(tables->comm_handler, t, "comm_table"); 1017df919b40SAdrian Hunter 1018df919b40SAdrian Hunter Py_DECREF(t); 1019df919b40SAdrian Hunter 1020df919b40SAdrian Hunter return 0; 1021df919b40SAdrian Hunter } 1022df919b40SAdrian Hunter 1023df919b40SAdrian Hunter static int python_export_comm_thread(struct db_export *dbe, u64 db_id, 1024df919b40SAdrian Hunter struct comm *comm, struct thread *thread) 1025df919b40SAdrian Hunter { 1026df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1027df919b40SAdrian Hunter PyObject *t; 1028df919b40SAdrian Hunter 1029df919b40SAdrian Hunter t = tuple_new(3); 1030df919b40SAdrian Hunter 1031df919b40SAdrian Hunter tuple_set_u64(t, 0, db_id); 1032df919b40SAdrian Hunter tuple_set_u64(t, 1, comm->db_id); 1033df919b40SAdrian Hunter tuple_set_u64(t, 2, thread->db_id); 1034df919b40SAdrian Hunter 1035df919b40SAdrian Hunter call_object(tables->comm_thread_handler, t, "comm_thread_table"); 1036df919b40SAdrian Hunter 1037df919b40SAdrian Hunter Py_DECREF(t); 1038df919b40SAdrian Hunter 1039df919b40SAdrian Hunter return 0; 1040df919b40SAdrian Hunter } 1041df919b40SAdrian Hunter 1042df919b40SAdrian Hunter static int python_export_dso(struct db_export *dbe, struct dso *dso, 1043df919b40SAdrian Hunter struct machine *machine) 1044df919b40SAdrian Hunter { 1045df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1046b5d8bbe8SMasami Hiramatsu char sbuild_id[SBUILD_ID_SIZE]; 1047df919b40SAdrian Hunter PyObject *t; 1048df919b40SAdrian Hunter 1049df919b40SAdrian Hunter build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1050df919b40SAdrian Hunter 1051df919b40SAdrian Hunter t = tuple_new(5); 1052df919b40SAdrian Hunter 1053df919b40SAdrian Hunter tuple_set_u64(t, 0, dso->db_id); 1054df919b40SAdrian Hunter tuple_set_u64(t, 1, machine->db_id); 1055df919b40SAdrian Hunter tuple_set_string(t, 2, dso->short_name); 1056df919b40SAdrian Hunter tuple_set_string(t, 3, dso->long_name); 1057df919b40SAdrian Hunter tuple_set_string(t, 4, sbuild_id); 1058df919b40SAdrian Hunter 1059df919b40SAdrian Hunter call_object(tables->dso_handler, t, "dso_table"); 1060df919b40SAdrian Hunter 1061df919b40SAdrian Hunter Py_DECREF(t); 1062df919b40SAdrian Hunter 1063df919b40SAdrian Hunter return 0; 1064df919b40SAdrian Hunter } 1065df919b40SAdrian Hunter 1066df919b40SAdrian Hunter static int python_export_symbol(struct db_export *dbe, struct symbol *sym, 1067df919b40SAdrian Hunter struct dso *dso) 1068df919b40SAdrian Hunter { 1069df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1070df919b40SAdrian Hunter u64 *sym_db_id = symbol__priv(sym); 1071df919b40SAdrian Hunter PyObject *t; 1072df919b40SAdrian Hunter 1073df919b40SAdrian Hunter t = tuple_new(6); 1074df919b40SAdrian Hunter 1075df919b40SAdrian Hunter tuple_set_u64(t, 0, *sym_db_id); 1076df919b40SAdrian Hunter tuple_set_u64(t, 1, dso->db_id); 1077df919b40SAdrian Hunter tuple_set_u64(t, 2, sym->start); 1078df919b40SAdrian Hunter tuple_set_u64(t, 3, sym->end); 1079df919b40SAdrian Hunter tuple_set_s32(t, 4, sym->binding); 1080df919b40SAdrian Hunter tuple_set_string(t, 5, sym->name); 1081df919b40SAdrian Hunter 1082df919b40SAdrian Hunter call_object(tables->symbol_handler, t, "symbol_table"); 1083df919b40SAdrian Hunter 1084df919b40SAdrian Hunter Py_DECREF(t); 1085df919b40SAdrian Hunter 1086df919b40SAdrian Hunter return 0; 1087df919b40SAdrian Hunter } 1088df919b40SAdrian Hunter 1089c29414f5SAdrian Hunter static int python_export_branch_type(struct db_export *dbe, u32 branch_type, 1090c29414f5SAdrian Hunter const char *name) 1091c29414f5SAdrian Hunter { 1092c29414f5SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1093c29414f5SAdrian Hunter PyObject *t; 1094c29414f5SAdrian Hunter 1095c29414f5SAdrian Hunter t = tuple_new(2); 1096c29414f5SAdrian Hunter 1097c29414f5SAdrian Hunter tuple_set_s32(t, 0, branch_type); 1098c29414f5SAdrian Hunter tuple_set_string(t, 1, name); 1099c29414f5SAdrian Hunter 1100c29414f5SAdrian Hunter call_object(tables->branch_type_handler, t, "branch_type_table"); 1101c29414f5SAdrian Hunter 1102c29414f5SAdrian Hunter Py_DECREF(t); 1103c29414f5SAdrian Hunter 1104c29414f5SAdrian Hunter return 0; 1105c29414f5SAdrian Hunter } 1106c29414f5SAdrian Hunter 1107df919b40SAdrian Hunter static int python_export_sample(struct db_export *dbe, 1108df919b40SAdrian Hunter struct export_sample *es) 1109df919b40SAdrian Hunter { 1110df919b40SAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 1111df919b40SAdrian Hunter PyObject *t; 1112df919b40SAdrian Hunter 11132c15f5ebSChris Phlipot t = tuple_new(22); 1114df919b40SAdrian Hunter 1115df919b40SAdrian Hunter tuple_set_u64(t, 0, es->db_id); 1116df919b40SAdrian Hunter tuple_set_u64(t, 1, es->evsel->db_id); 1117df919b40SAdrian Hunter tuple_set_u64(t, 2, es->al->machine->db_id); 1118b83e868dSArnaldo Carvalho de Melo tuple_set_u64(t, 3, es->al->thread->db_id); 1119df919b40SAdrian Hunter tuple_set_u64(t, 4, es->comm_db_id); 1120df919b40SAdrian Hunter tuple_set_u64(t, 5, es->dso_db_id); 1121df919b40SAdrian Hunter tuple_set_u64(t, 6, es->sym_db_id); 1122df919b40SAdrian Hunter tuple_set_u64(t, 7, es->offset); 1123df919b40SAdrian Hunter tuple_set_u64(t, 8, es->sample->ip); 1124df919b40SAdrian Hunter tuple_set_u64(t, 9, es->sample->time); 1125df919b40SAdrian Hunter tuple_set_s32(t, 10, es->sample->cpu); 1126df919b40SAdrian Hunter tuple_set_u64(t, 11, es->addr_dso_db_id); 1127df919b40SAdrian Hunter tuple_set_u64(t, 12, es->addr_sym_db_id); 1128df919b40SAdrian Hunter tuple_set_u64(t, 13, es->addr_offset); 1129df919b40SAdrian Hunter tuple_set_u64(t, 14, es->sample->addr); 1130df919b40SAdrian Hunter tuple_set_u64(t, 15, es->sample->period); 1131df919b40SAdrian Hunter tuple_set_u64(t, 16, es->sample->weight); 1132df919b40SAdrian Hunter tuple_set_u64(t, 17, es->sample->transaction); 1133df919b40SAdrian Hunter tuple_set_u64(t, 18, es->sample->data_src); 1134c29414f5SAdrian Hunter tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK); 1135c29414f5SAdrian Hunter tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX)); 11362c15f5ebSChris Phlipot tuple_set_u64(t, 21, es->call_path_id); 1137df919b40SAdrian Hunter 1138df919b40SAdrian Hunter call_object(tables->sample_handler, t, "sample_table"); 1139df919b40SAdrian Hunter 1140df919b40SAdrian Hunter Py_DECREF(t); 1141df919b40SAdrian Hunter 1142df919b40SAdrian Hunter return 0; 1143df919b40SAdrian Hunter } 1144df919b40SAdrian Hunter 11456a70307dSAdrian Hunter static int python_export_call_path(struct db_export *dbe, struct call_path *cp) 11466a70307dSAdrian Hunter { 11476a70307dSAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 11486a70307dSAdrian Hunter PyObject *t; 11496a70307dSAdrian Hunter u64 parent_db_id, sym_db_id; 11506a70307dSAdrian Hunter 11516a70307dSAdrian Hunter parent_db_id = cp->parent ? cp->parent->db_id : 0; 11526a70307dSAdrian Hunter sym_db_id = cp->sym ? *(u64 *)symbol__priv(cp->sym) : 0; 11536a70307dSAdrian Hunter 11546a70307dSAdrian Hunter t = tuple_new(4); 11556a70307dSAdrian Hunter 11566a70307dSAdrian Hunter tuple_set_u64(t, 0, cp->db_id); 11576a70307dSAdrian Hunter tuple_set_u64(t, 1, parent_db_id); 11586a70307dSAdrian Hunter tuple_set_u64(t, 2, sym_db_id); 11596a70307dSAdrian Hunter tuple_set_u64(t, 3, cp->ip); 11606a70307dSAdrian Hunter 11616a70307dSAdrian Hunter call_object(tables->call_path_handler, t, "call_path_table"); 11626a70307dSAdrian Hunter 11636a70307dSAdrian Hunter Py_DECREF(t); 11646a70307dSAdrian Hunter 11656a70307dSAdrian Hunter return 0; 11666a70307dSAdrian Hunter } 11676a70307dSAdrian Hunter 11686a70307dSAdrian Hunter static int python_export_call_return(struct db_export *dbe, 11696a70307dSAdrian Hunter struct call_return *cr) 11706a70307dSAdrian Hunter { 11716a70307dSAdrian Hunter struct tables *tables = container_of(dbe, struct tables, dbe); 11726a70307dSAdrian Hunter u64 comm_db_id = cr->comm ? cr->comm->db_id : 0; 11736a70307dSAdrian Hunter PyObject *t; 11746a70307dSAdrian Hunter 11756a70307dSAdrian Hunter t = tuple_new(11); 11766a70307dSAdrian Hunter 11776a70307dSAdrian Hunter tuple_set_u64(t, 0, cr->db_id); 11786a70307dSAdrian Hunter tuple_set_u64(t, 1, cr->thread->db_id); 11796a70307dSAdrian Hunter tuple_set_u64(t, 2, comm_db_id); 11806a70307dSAdrian Hunter tuple_set_u64(t, 3, cr->cp->db_id); 11816a70307dSAdrian Hunter tuple_set_u64(t, 4, cr->call_time); 11826a70307dSAdrian Hunter tuple_set_u64(t, 5, cr->return_time); 11836a70307dSAdrian Hunter tuple_set_u64(t, 6, cr->branch_count); 11846a70307dSAdrian Hunter tuple_set_u64(t, 7, cr->call_ref); 11856a70307dSAdrian Hunter tuple_set_u64(t, 8, cr->return_ref); 11866a70307dSAdrian Hunter tuple_set_u64(t, 9, cr->cp->parent->db_id); 11876a70307dSAdrian Hunter tuple_set_s32(t, 10, cr->flags); 11886a70307dSAdrian Hunter 11896a70307dSAdrian Hunter call_object(tables->call_return_handler, t, "call_return_table"); 11906a70307dSAdrian Hunter 11916a70307dSAdrian Hunter Py_DECREF(t); 11926a70307dSAdrian Hunter 11936a70307dSAdrian Hunter return 0; 11946a70307dSAdrian Hunter } 11956a70307dSAdrian Hunter 11966a70307dSAdrian Hunter static int python_process_call_return(struct call_return *cr, void *data) 11976a70307dSAdrian Hunter { 11986a70307dSAdrian Hunter struct db_export *dbe = data; 11996a70307dSAdrian Hunter 12006a70307dSAdrian Hunter return db_export__call_return(dbe, cr); 12016a70307dSAdrian Hunter } 12026a70307dSAdrian Hunter 1203b7fff6b5SArnaldo Carvalho de Melo static void python_process_general_event(struct perf_sample *sample, 12046a6daec2SFeng Tang struct perf_evsel *evsel, 120587b6a3adSFeng Tang struct addr_location *al) 12066a6daec2SFeng Tang { 1207892e76b2SArun Kalyanasundaram PyObject *handler, *t, *dict, *callchain; 12086a6daec2SFeng Tang static char handler_name[64]; 12096a6daec2SFeng Tang unsigned n = 0; 12106a6daec2SFeng Tang 1211e9f9a9caSArun Kalyanasundaram snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 1212e9f9a9caSArun Kalyanasundaram 1213e9f9a9caSArun Kalyanasundaram handler = get_handler(handler_name); 1214e9f9a9caSArun Kalyanasundaram if (!handler) 1215e9f9a9caSArun Kalyanasundaram return; 1216e9f9a9caSArun Kalyanasundaram 1217fd6b858aSFeng Tang /* 1218fd6b858aSFeng Tang * Use the MAX_FIELDS to make the function expandable, though 121987b6a3adSFeng Tang * currently there is only one item for the tuple. 1220fd6b858aSFeng Tang */ 12216a6daec2SFeng Tang t = PyTuple_New(MAX_FIELDS); 12226a6daec2SFeng Tang if (!t) 12236a6daec2SFeng Tang Py_FatalError("couldn't create Python tuple"); 12246a6daec2SFeng Tang 12250f5f5bcdSJoseph Schuchart /* ip unwinding */ 12260f5f5bcdSJoseph Schuchart callchain = python_process_callchain(sample, evsel, al); 1227892e76b2SArun Kalyanasundaram dict = get_perf_sample_dict(sample, evsel, al, callchain); 12280f5f5bcdSJoseph Schuchart 1229fd6b858aSFeng Tang PyTuple_SetItem(t, n++, dict); 12306a6daec2SFeng Tang if (_PyTuple_Resize(&t, n) == -1) 12316a6daec2SFeng Tang Py_FatalError("error resizing Python tuple"); 12326a6daec2SFeng Tang 1233a5563edfSAdrian Hunter call_object(handler, t, handler_name); 1234e9f9a9caSArun Kalyanasundaram 12356a6daec2SFeng Tang Py_DECREF(t); 12366a6daec2SFeng Tang } 12376a6daec2SFeng Tang 1238df919b40SAdrian Hunter static void python_process_event(union perf_event *event, 12396a6daec2SFeng Tang struct perf_sample *sample, 12406a6daec2SFeng Tang struct perf_evsel *evsel, 124173994dc1SFeng Tang struct addr_location *al) 12426a6daec2SFeng Tang { 1243df919b40SAdrian Hunter struct tables *tables = &tables_global; 1244df919b40SAdrian Hunter 12456a6daec2SFeng Tang switch (evsel->attr.type) { 12466a6daec2SFeng Tang case PERF_TYPE_TRACEPOINT: 1247f9d5d549SArnaldo Carvalho de Melo python_process_tracepoint(sample, evsel, al); 12486a6daec2SFeng Tang break; 12496a6daec2SFeng Tang /* Reserve for future process_hw/sw/raw APIs */ 12506a6daec2SFeng Tang default: 1251df919b40SAdrian Hunter if (tables->db_export_mode) 12527327259dSArnaldo Carvalho de Melo db_export__sample(&tables->dbe, event, sample, evsel, al); 1253df919b40SAdrian Hunter else 1254f9d5d549SArnaldo Carvalho de Melo python_process_general_event(sample, evsel, al); 12556a6daec2SFeng Tang } 12566a6daec2SFeng Tang } 12576a6daec2SFeng Tang 1258aef90263SJiri Olsa static void get_handler_name(char *str, size_t size, 1259aef90263SJiri Olsa struct perf_evsel *evsel) 1260aef90263SJiri Olsa { 1261aef90263SJiri Olsa char *p = str; 1262aef90263SJiri Olsa 1263aef90263SJiri Olsa scnprintf(str, size, "stat__%s", perf_evsel__name(evsel)); 1264aef90263SJiri Olsa 1265aef90263SJiri Olsa while ((p = strchr(p, ':'))) { 1266aef90263SJiri Olsa *p = '_'; 1267aef90263SJiri Olsa p++; 1268aef90263SJiri Olsa } 1269aef90263SJiri Olsa } 1270aef90263SJiri Olsa 1271aef90263SJiri Olsa static void 1272aef90263SJiri Olsa process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, 1273aef90263SJiri Olsa struct perf_counts_values *count) 1274aef90263SJiri Olsa { 1275aef90263SJiri Olsa PyObject *handler, *t; 1276aef90263SJiri Olsa static char handler_name[256]; 1277aef90263SJiri Olsa int n = 0; 1278aef90263SJiri Olsa 1279aef90263SJiri Olsa t = PyTuple_New(MAX_FIELDS); 1280aef90263SJiri Olsa if (!t) 1281aef90263SJiri Olsa Py_FatalError("couldn't create Python tuple"); 1282aef90263SJiri Olsa 1283aef90263SJiri Olsa get_handler_name(handler_name, sizeof(handler_name), 1284aef90263SJiri Olsa counter); 1285aef90263SJiri Olsa 1286aef90263SJiri Olsa handler = get_handler(handler_name); 1287aef90263SJiri Olsa if (!handler) { 1288aef90263SJiri Olsa pr_debug("can't find python handler %s\n", handler_name); 1289aef90263SJiri Olsa return; 1290aef90263SJiri Olsa } 1291aef90263SJiri Olsa 129266dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu)); 129366dfdff0SJaroslav Škarvada PyTuple_SetItem(t, n++, _PyLong_FromLong(thread)); 1294aef90263SJiri Olsa 1295aef90263SJiri Olsa tuple_set_u64(t, n++, tstamp); 1296aef90263SJiri Olsa tuple_set_u64(t, n++, count->val); 1297aef90263SJiri Olsa tuple_set_u64(t, n++, count->ena); 1298aef90263SJiri Olsa tuple_set_u64(t, n++, count->run); 1299aef90263SJiri Olsa 1300aef90263SJiri Olsa if (_PyTuple_Resize(&t, n) == -1) 1301aef90263SJiri Olsa Py_FatalError("error resizing Python tuple"); 1302aef90263SJiri Olsa 1303aef90263SJiri Olsa call_object(handler, t, handler_name); 1304aef90263SJiri Olsa 1305aef90263SJiri Olsa Py_DECREF(t); 1306aef90263SJiri Olsa } 1307aef90263SJiri Olsa 1308aef90263SJiri Olsa static void python_process_stat(struct perf_stat_config *config, 1309aef90263SJiri Olsa struct perf_evsel *counter, u64 tstamp) 1310aef90263SJiri Olsa { 1311aef90263SJiri Olsa struct thread_map *threads = counter->threads; 1312aef90263SJiri Olsa struct cpu_map *cpus = counter->cpus; 1313aef90263SJiri Olsa int cpu, thread; 1314aef90263SJiri Olsa 1315aef90263SJiri Olsa if (config->aggr_mode == AGGR_GLOBAL) { 1316aef90263SJiri Olsa process_stat(counter, -1, -1, tstamp, 1317aef90263SJiri Olsa &counter->counts->aggr); 1318aef90263SJiri Olsa return; 1319aef90263SJiri Olsa } 1320aef90263SJiri Olsa 1321aef90263SJiri Olsa for (thread = 0; thread < threads->nr; thread++) { 1322aef90263SJiri Olsa for (cpu = 0; cpu < cpus->nr; cpu++) { 1323aef90263SJiri Olsa process_stat(counter, cpus->map[cpu], 1324aef90263SJiri Olsa thread_map__pid(threads, thread), tstamp, 1325aef90263SJiri Olsa perf_counts(counter->counts, cpu, thread)); 1326aef90263SJiri Olsa } 1327aef90263SJiri Olsa } 1328aef90263SJiri Olsa } 1329aef90263SJiri Olsa 1330aef90263SJiri Olsa static void python_process_stat_interval(u64 tstamp) 1331aef90263SJiri Olsa { 1332aef90263SJiri Olsa PyObject *handler, *t; 1333aef90263SJiri Olsa static const char handler_name[] = "stat__interval"; 1334aef90263SJiri Olsa int n = 0; 1335aef90263SJiri Olsa 1336aef90263SJiri Olsa t = PyTuple_New(MAX_FIELDS); 1337aef90263SJiri Olsa if (!t) 1338aef90263SJiri Olsa Py_FatalError("couldn't create Python tuple"); 1339aef90263SJiri Olsa 1340aef90263SJiri Olsa handler = get_handler(handler_name); 1341aef90263SJiri Olsa if (!handler) { 1342aef90263SJiri Olsa pr_debug("can't find python handler %s\n", handler_name); 1343aef90263SJiri Olsa return; 1344aef90263SJiri Olsa } 1345aef90263SJiri Olsa 1346aef90263SJiri Olsa tuple_set_u64(t, n++, tstamp); 1347aef90263SJiri Olsa 1348aef90263SJiri Olsa if (_PyTuple_Resize(&t, n) == -1) 1349aef90263SJiri Olsa Py_FatalError("error resizing Python tuple"); 1350aef90263SJiri Olsa 1351aef90263SJiri Olsa call_object(handler, t, handler_name); 1352aef90263SJiri Olsa 1353aef90263SJiri Olsa Py_DECREF(t); 1354aef90263SJiri Olsa } 1355aef90263SJiri Olsa 13567e4b21b8STom Zanussi static int run_start_sub(void) 13577e4b21b8STom Zanussi { 13587e4b21b8STom Zanussi main_module = PyImport_AddModule("__main__"); 13597e4b21b8STom Zanussi if (main_module == NULL) 13607e4b21b8STom Zanussi return -1; 13617e4b21b8STom Zanussi Py_INCREF(main_module); 13627e4b21b8STom Zanussi 13637e4b21b8STom Zanussi main_dict = PyModule_GetDict(main_module); 1364a5563edfSAdrian Hunter if (main_dict == NULL) 13657e4b21b8STom Zanussi goto error; 13667e4b21b8STom Zanussi Py_INCREF(main_dict); 13677e4b21b8STom Zanussi 1368a5563edfSAdrian Hunter try_call_object("trace_begin", NULL); 13697e4b21b8STom Zanussi 1370a5563edfSAdrian Hunter return 0; 13717e4b21b8STom Zanussi 13727e4b21b8STom Zanussi error: 13737e4b21b8STom Zanussi Py_XDECREF(main_dict); 13747e4b21b8STom Zanussi Py_XDECREF(main_module); 1375a5563edfSAdrian Hunter return -1; 13767e4b21b8STom Zanussi } 13777e4b21b8STom Zanussi 1378df919b40SAdrian Hunter #define SET_TABLE_HANDLER_(name, handler_name, table_name) do { \ 1379df919b40SAdrian Hunter tables->handler_name = get_handler(#table_name); \ 1380df919b40SAdrian Hunter if (tables->handler_name) \ 1381df919b40SAdrian Hunter tables->dbe.export_ ## name = python_export_ ## name; \ 1382df919b40SAdrian Hunter } while (0) 1383df919b40SAdrian Hunter 1384df919b40SAdrian Hunter #define SET_TABLE_HANDLER(name) \ 1385df919b40SAdrian Hunter SET_TABLE_HANDLER_(name, name ## _handler, name ## _table) 1386df919b40SAdrian Hunter 1387df919b40SAdrian Hunter static void set_table_handlers(struct tables *tables) 1388df919b40SAdrian Hunter { 1389df919b40SAdrian Hunter const char *perf_db_export_mode = "perf_db_export_mode"; 13906a70307dSAdrian Hunter const char *perf_db_export_calls = "perf_db_export_calls"; 13912c15f5ebSChris Phlipot const char *perf_db_export_callchains = "perf_db_export_callchains"; 13922c15f5ebSChris Phlipot PyObject *db_export_mode, *db_export_calls, *db_export_callchains; 13936a70307dSAdrian Hunter bool export_calls = false; 13942c15f5ebSChris Phlipot bool export_callchains = false; 1395df919b40SAdrian Hunter int ret; 1396df919b40SAdrian Hunter 1397df919b40SAdrian Hunter memset(tables, 0, sizeof(struct tables)); 1398df919b40SAdrian Hunter if (db_export__init(&tables->dbe)) 1399df919b40SAdrian Hunter Py_FatalError("failed to initialize export"); 1400df919b40SAdrian Hunter 1401df919b40SAdrian Hunter db_export_mode = PyDict_GetItemString(main_dict, perf_db_export_mode); 1402df919b40SAdrian Hunter if (!db_export_mode) 1403df919b40SAdrian Hunter return; 1404df919b40SAdrian Hunter 1405df919b40SAdrian Hunter ret = PyObject_IsTrue(db_export_mode); 1406df919b40SAdrian Hunter if (ret == -1) 1407df919b40SAdrian Hunter handler_call_die(perf_db_export_mode); 1408df919b40SAdrian Hunter if (!ret) 1409df919b40SAdrian Hunter return; 1410df919b40SAdrian Hunter 14112c15f5ebSChris Phlipot /* handle export calls */ 14126a70307dSAdrian Hunter tables->dbe.crp = NULL; 14136a70307dSAdrian Hunter db_export_calls = PyDict_GetItemString(main_dict, perf_db_export_calls); 14146a70307dSAdrian Hunter if (db_export_calls) { 14156a70307dSAdrian Hunter ret = PyObject_IsTrue(db_export_calls); 14166a70307dSAdrian Hunter if (ret == -1) 14176a70307dSAdrian Hunter handler_call_die(perf_db_export_calls); 14186a70307dSAdrian Hunter export_calls = !!ret; 14196a70307dSAdrian Hunter } 14206a70307dSAdrian Hunter 14216a70307dSAdrian Hunter if (export_calls) { 14226a70307dSAdrian Hunter tables->dbe.crp = 14236a70307dSAdrian Hunter call_return_processor__new(python_process_call_return, 14246a70307dSAdrian Hunter &tables->dbe); 14256a70307dSAdrian Hunter if (!tables->dbe.crp) 14266a70307dSAdrian Hunter Py_FatalError("failed to create calls processor"); 14276a70307dSAdrian Hunter } 14286a70307dSAdrian Hunter 14292c15f5ebSChris Phlipot /* handle export callchains */ 14302c15f5ebSChris Phlipot tables->dbe.cpr = NULL; 14312c15f5ebSChris Phlipot db_export_callchains = PyDict_GetItemString(main_dict, 14322c15f5ebSChris Phlipot perf_db_export_callchains); 14332c15f5ebSChris Phlipot if (db_export_callchains) { 14342c15f5ebSChris Phlipot ret = PyObject_IsTrue(db_export_callchains); 14352c15f5ebSChris Phlipot if (ret == -1) 14362c15f5ebSChris Phlipot handler_call_die(perf_db_export_callchains); 14372c15f5ebSChris Phlipot export_callchains = !!ret; 14382c15f5ebSChris Phlipot } 14392c15f5ebSChris Phlipot 14402c15f5ebSChris Phlipot if (export_callchains) { 14412c15f5ebSChris Phlipot /* 14422c15f5ebSChris Phlipot * Attempt to use the call path root from the call return 14432c15f5ebSChris Phlipot * processor, if the call return processor is in use. Otherwise, 14442c15f5ebSChris Phlipot * we allocate a new call path root. This prevents exporting 14452c15f5ebSChris Phlipot * duplicate call path ids when both are in use simultaniously. 14462c15f5ebSChris Phlipot */ 14472c15f5ebSChris Phlipot if (tables->dbe.crp) 14482c15f5ebSChris Phlipot tables->dbe.cpr = tables->dbe.crp->cpr; 14492c15f5ebSChris Phlipot else 14502c15f5ebSChris Phlipot tables->dbe.cpr = call_path_root__new(); 14512c15f5ebSChris Phlipot 14522c15f5ebSChris Phlipot if (!tables->dbe.cpr) 1453aff63340SChris Phlipot Py_FatalError("failed to create call path root"); 14542c15f5ebSChris Phlipot } 14552c15f5ebSChris Phlipot 1456df919b40SAdrian Hunter tables->db_export_mode = true; 1457df919b40SAdrian Hunter /* 1458df919b40SAdrian Hunter * Reserve per symbol space for symbol->db_id via symbol__priv() 1459df919b40SAdrian Hunter */ 1460df919b40SAdrian Hunter symbol_conf.priv_size = sizeof(u64); 1461df919b40SAdrian Hunter 1462df919b40SAdrian Hunter SET_TABLE_HANDLER(evsel); 1463df919b40SAdrian Hunter SET_TABLE_HANDLER(machine); 1464df919b40SAdrian Hunter SET_TABLE_HANDLER(thread); 1465df919b40SAdrian Hunter SET_TABLE_HANDLER(comm); 1466df919b40SAdrian Hunter SET_TABLE_HANDLER(comm_thread); 1467df919b40SAdrian Hunter SET_TABLE_HANDLER(dso); 1468df919b40SAdrian Hunter SET_TABLE_HANDLER(symbol); 1469c29414f5SAdrian Hunter SET_TABLE_HANDLER(branch_type); 1470df919b40SAdrian Hunter SET_TABLE_HANDLER(sample); 14716a70307dSAdrian Hunter SET_TABLE_HANDLER(call_path); 14726a70307dSAdrian Hunter SET_TABLE_HANDLER(call_return); 1473df919b40SAdrian Hunter } 1474df919b40SAdrian Hunter 147566dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3 147666dfdff0SJaroslav Škarvada static void _free_command_line(const char **command_line, int num) 147766dfdff0SJaroslav Škarvada { 147866dfdff0SJaroslav Škarvada free(command_line); 147966dfdff0SJaroslav Škarvada } 148066dfdff0SJaroslav Škarvada #else 148166dfdff0SJaroslav Škarvada static void _free_command_line(wchar_t **command_line, int num) 148266dfdff0SJaroslav Škarvada { 148366dfdff0SJaroslav Škarvada int i; 148466dfdff0SJaroslav Škarvada for (i = 0; i < num; i++) 148566dfdff0SJaroslav Škarvada PyMem_RawFree(command_line[i]); 148666dfdff0SJaroslav Škarvada free(command_line); 148766dfdff0SJaroslav Škarvada } 148866dfdff0SJaroslav Škarvada #endif 148966dfdff0SJaroslav Škarvada 149066dfdff0SJaroslav Škarvada 14917e4b21b8STom Zanussi /* 14927e4b21b8STom Zanussi * Start trace script 14937e4b21b8STom Zanussi */ 14947e4b21b8STom Zanussi static int python_start_script(const char *script, int argc, const char **argv) 14957e4b21b8STom Zanussi { 1496df919b40SAdrian Hunter struct tables *tables = &tables_global; 149766dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3 14987e4b21b8STom Zanussi const char **command_line; 149966dfdff0SJaroslav Škarvada #else 150066dfdff0SJaroslav Škarvada wchar_t **command_line; 150166dfdff0SJaroslav Škarvada #endif 15027e4b21b8STom Zanussi char buf[PATH_MAX]; 15037e4b21b8STom Zanussi int i, err = 0; 15047e4b21b8STom Zanussi FILE *fp; 15057e4b21b8STom Zanussi 150666dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3 15077e4b21b8STom Zanussi command_line = malloc((argc + 1) * sizeof(const char *)); 15087e4b21b8STom Zanussi command_line[0] = script; 15097e4b21b8STom Zanussi for (i = 1; i < argc + 1; i++) 15107e4b21b8STom Zanussi command_line[i] = argv[i - 1]; 151166dfdff0SJaroslav Škarvada #else 151266dfdff0SJaroslav Škarvada command_line = malloc((argc + 1) * sizeof(wchar_t *)); 151366dfdff0SJaroslav Škarvada command_line[0] = Py_DecodeLocale(script, NULL); 151466dfdff0SJaroslav Škarvada for (i = 1; i < argc + 1; i++) 151566dfdff0SJaroslav Škarvada command_line[i] = Py_DecodeLocale(argv[i - 1], NULL); 151666dfdff0SJaroslav Škarvada #endif 15177e4b21b8STom Zanussi 15187e4b21b8STom Zanussi Py_Initialize(); 15197e4b21b8STom Zanussi 152066dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3 15217e4b21b8STom Zanussi initperf_trace_context(); 15227e4b21b8STom Zanussi PySys_SetArgv(argc + 1, (char **)command_line); 152366dfdff0SJaroslav Škarvada #else 152466dfdff0SJaroslav Škarvada PyInit_perf_trace_context(); 152566dfdff0SJaroslav Škarvada PySys_SetArgv(argc + 1, command_line); 152666dfdff0SJaroslav Škarvada #endif 15277e4b21b8STom Zanussi 15287e4b21b8STom Zanussi fp = fopen(script, "r"); 15297e4b21b8STom Zanussi if (!fp) { 15307e4b21b8STom Zanussi sprintf(buf, "Can't open python script \"%s\"", script); 15317e4b21b8STom Zanussi perror(buf); 15327e4b21b8STom Zanussi err = -1; 15337e4b21b8STom Zanussi goto error; 15347e4b21b8STom Zanussi } 15357e4b21b8STom Zanussi 15367e4b21b8STom Zanussi err = PyRun_SimpleFile(fp, script); 15377e4b21b8STom Zanussi if (err) { 15387e4b21b8STom Zanussi fprintf(stderr, "Error running python script %s\n", script); 15397e4b21b8STom Zanussi goto error; 15407e4b21b8STom Zanussi } 15417e4b21b8STom Zanussi 15427e4b21b8STom Zanussi err = run_start_sub(); 15437e4b21b8STom Zanussi if (err) { 15447e4b21b8STom Zanussi fprintf(stderr, "Error starting python script %s\n", script); 15457e4b21b8STom Zanussi goto error; 15467e4b21b8STom Zanussi } 15477e4b21b8STom Zanussi 1548df919b40SAdrian Hunter set_table_handlers(tables); 1549df919b40SAdrian Hunter 1550c29414f5SAdrian Hunter if (tables->db_export_mode) { 1551c29414f5SAdrian Hunter err = db_export__branch_types(&tables->dbe); 1552c29414f5SAdrian Hunter if (err) 1553c29414f5SAdrian Hunter goto error; 1554c29414f5SAdrian Hunter } 1555c29414f5SAdrian Hunter 155666dfdff0SJaroslav Škarvada _free_command_line(command_line, argc + 1); 1557979ac257SColin Ian King 15587e4b21b8STom Zanussi return err; 15597e4b21b8STom Zanussi error: 15607e4b21b8STom Zanussi Py_Finalize(); 156166dfdff0SJaroslav Škarvada _free_command_line(command_line, argc + 1); 15627e4b21b8STom Zanussi 15637e4b21b8STom Zanussi return err; 15647e4b21b8STom Zanussi } 15657e4b21b8STom Zanussi 1566d445dd2aSAdrian Hunter static int python_flush_script(void) 1567d445dd2aSAdrian Hunter { 1568758008b2SAdrian Hunter struct tables *tables = &tables_global; 1569758008b2SAdrian Hunter 1570758008b2SAdrian Hunter return db_export__flush(&tables->dbe); 1571d445dd2aSAdrian Hunter } 1572d445dd2aSAdrian Hunter 15737e4b21b8STom Zanussi /* 15747e4b21b8STom Zanussi * Stop trace script 15757e4b21b8STom Zanussi */ 15767e4b21b8STom Zanussi static int python_stop_script(void) 15777e4b21b8STom Zanussi { 1578df919b40SAdrian Hunter struct tables *tables = &tables_global; 1579df919b40SAdrian Hunter 1580a5563edfSAdrian Hunter try_call_object("trace_end", NULL); 15817e4b21b8STom Zanussi 1582df919b40SAdrian Hunter db_export__exit(&tables->dbe); 1583df919b40SAdrian Hunter 15847e4b21b8STom Zanussi Py_XDECREF(main_dict); 15857e4b21b8STom Zanussi Py_XDECREF(main_module); 15867e4b21b8STom Zanussi Py_Finalize(); 15877e4b21b8STom Zanussi 1588a5563edfSAdrian Hunter return 0; 15897e4b21b8STom Zanussi } 15907e4b21b8STom Zanussi 1591096177a8STzvetomir Stoyanov (VMware) static int python_generate_script(struct tep_handle *pevent, const char *outfile) 15927e4b21b8STom Zanussi { 15934963b0f8STzvetomir Stoyanov (VMware) struct tep_event_format *event = NULL; 15942c92f982STzvetomir Stoyanov (VMware) struct tep_format_field *f; 15957e4b21b8STom Zanussi char fname[PATH_MAX]; 15967e4b21b8STom Zanussi int not_first, count; 15977e4b21b8STom Zanussi FILE *ofp; 15987e4b21b8STom Zanussi 15997e4b21b8STom Zanussi sprintf(fname, "%s.py", outfile); 16007e4b21b8STom Zanussi ofp = fopen(fname, "w"); 16017e4b21b8STom Zanussi if (ofp == NULL) { 16027e4b21b8STom Zanussi fprintf(stderr, "couldn't open %s\n", fname); 16037e4b21b8STom Zanussi return -1; 16047e4b21b8STom Zanussi } 1605133dc4c3SIngo Molnar fprintf(ofp, "# perf script event handlers, " 1606133dc4c3SIngo Molnar "generated by perf script -g python\n"); 16077e4b21b8STom Zanussi 16087e4b21b8STom Zanussi fprintf(ofp, "# Licensed under the terms of the GNU GPL" 16097e4b21b8STom Zanussi " License version 2\n\n"); 16107e4b21b8STom Zanussi 16117e4b21b8STom Zanussi fprintf(ofp, "# The common_* event handler fields are the most useful " 16127e4b21b8STom Zanussi "fields common to\n"); 16137e4b21b8STom Zanussi 16147e4b21b8STom Zanussi fprintf(ofp, "# all events. They don't necessarily correspond to " 16157e4b21b8STom Zanussi "the 'common_*' fields\n"); 16167e4b21b8STom Zanussi 16177e4b21b8STom Zanussi fprintf(ofp, "# in the format files. Those fields not available as " 16187e4b21b8STom Zanussi "handler params can\n"); 16197e4b21b8STom Zanussi 16207e4b21b8STom Zanussi fprintf(ofp, "# be retrieved using Python functions of the form " 16217e4b21b8STom Zanussi "common_*(context).\n"); 16227e4b21b8STom Zanussi 1623c76132dcSSeongJae Park fprintf(ofp, "# See the perf-script-python Documentation for the list " 16247e4b21b8STom Zanussi "of available functions.\n\n"); 16257e4b21b8STom Zanussi 1626877cc639SJeremy Cline fprintf(ofp, "from __future__ import print_function\n\n"); 16277e4b21b8STom Zanussi fprintf(ofp, "import os\n"); 16287e4b21b8STom Zanussi fprintf(ofp, "import sys\n\n"); 16297e4b21b8STom Zanussi 16307e4b21b8STom Zanussi fprintf(ofp, "sys.path.append(os.environ['PERF_EXEC_PATH'] + \\\n"); 16317e4b21b8STom Zanussi fprintf(ofp, "\t'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')\n"); 16327e4b21b8STom Zanussi fprintf(ofp, "\nfrom perf_trace_context import *\n"); 16337e4b21b8STom Zanussi fprintf(ofp, "from Core import *\n\n\n"); 16347e4b21b8STom Zanussi 16357e4b21b8STom Zanussi fprintf(ofp, "def trace_begin():\n"); 1636877cc639SJeremy Cline fprintf(ofp, "\tprint(\"in trace_begin\")\n\n"); 16377e4b21b8STom Zanussi 16387e4b21b8STom Zanussi fprintf(ofp, "def trace_end():\n"); 1639877cc639SJeremy Cline fprintf(ofp, "\tprint(\"in trace_end\")\n\n"); 16407e4b21b8STom Zanussi 1641da378962SArnaldo Carvalho de Melo while ((event = trace_find_next_event(pevent, event))) { 16427e4b21b8STom Zanussi fprintf(ofp, "def %s__%s(", event->system, event->name); 16437e4b21b8STom Zanussi fprintf(ofp, "event_name, "); 16447e4b21b8STom Zanussi fprintf(ofp, "context, "); 16457e4b21b8STom Zanussi fprintf(ofp, "common_cpu,\n"); 16467e4b21b8STom Zanussi fprintf(ofp, "\tcommon_secs, "); 16477e4b21b8STom Zanussi fprintf(ofp, "common_nsecs, "); 16487e4b21b8STom Zanussi fprintf(ofp, "common_pid, "); 16497e4b21b8STom Zanussi fprintf(ofp, "common_comm,\n\t"); 16500f5f5bcdSJoseph Schuchart fprintf(ofp, "common_callchain, "); 16517e4b21b8STom Zanussi 16527e4b21b8STom Zanussi not_first = 0; 16537e4b21b8STom Zanussi count = 0; 16547e4b21b8STom Zanussi 16557e4b21b8STom Zanussi for (f = event->format.fields; f; f = f->next) { 16567e4b21b8STom Zanussi if (not_first++) 16577e4b21b8STom Zanussi fprintf(ofp, ", "); 16587e4b21b8STom Zanussi if (++count % 5 == 0) 16597e4b21b8STom Zanussi fprintf(ofp, "\n\t"); 16607e4b21b8STom Zanussi 16617e4b21b8STom Zanussi fprintf(ofp, "%s", f->name); 16627e4b21b8STom Zanussi } 1663a6418605SArun Kalyanasundaram if (not_first++) 1664a6418605SArun Kalyanasundaram fprintf(ofp, ", "); 1665a6418605SArun Kalyanasundaram if (++count % 5 == 0) 1666a6418605SArun Kalyanasundaram fprintf(ofp, "\n\t\t"); 1667a6418605SArun Kalyanasundaram fprintf(ofp, "perf_sample_dict"); 1668a6418605SArun Kalyanasundaram 16697e4b21b8STom Zanussi fprintf(ofp, "):\n"); 16707e4b21b8STom Zanussi 16717e4b21b8STom Zanussi fprintf(ofp, "\t\tprint_header(event_name, common_cpu, " 16727e4b21b8STom Zanussi "common_secs, common_nsecs,\n\t\t\t" 16737e4b21b8STom Zanussi "common_pid, common_comm)\n\n"); 16747e4b21b8STom Zanussi 1675877cc639SJeremy Cline fprintf(ofp, "\t\tprint(\""); 16767e4b21b8STom Zanussi 16777e4b21b8STom Zanussi not_first = 0; 16787e4b21b8STom Zanussi count = 0; 16797e4b21b8STom Zanussi 16807e4b21b8STom Zanussi for (f = event->format.fields; f; f = f->next) { 16817e4b21b8STom Zanussi if (not_first++) 16827e4b21b8STom Zanussi fprintf(ofp, ", "); 16837e4b21b8STom Zanussi if (count && count % 3 == 0) { 16847e4b21b8STom Zanussi fprintf(ofp, "\" \\\n\t\t\""); 16857e4b21b8STom Zanussi } 16867e4b21b8STom Zanussi count++; 16877e4b21b8STom Zanussi 16887e4b21b8STom Zanussi fprintf(ofp, "%s=", f->name); 1689*bb39ccb2STzvetomir Stoyanov (VMware) if (f->flags & TEP_FIELD_IS_STRING || 1690*bb39ccb2STzvetomir Stoyanov (VMware) f->flags & TEP_FIELD_IS_FLAG || 1691*bb39ccb2STzvetomir Stoyanov (VMware) f->flags & TEP_FIELD_IS_ARRAY || 1692*bb39ccb2STzvetomir Stoyanov (VMware) f->flags & TEP_FIELD_IS_SYMBOLIC) 16937e4b21b8STom Zanussi fprintf(ofp, "%%s"); 1694*bb39ccb2STzvetomir Stoyanov (VMware) else if (f->flags & TEP_FIELD_IS_SIGNED) 16957e4b21b8STom Zanussi fprintf(ofp, "%%d"); 16967e4b21b8STom Zanussi else 16977e4b21b8STom Zanussi fprintf(ofp, "%%u"); 16987e4b21b8STom Zanussi } 16997e4b21b8STom Zanussi 17000f5f5bcdSJoseph Schuchart fprintf(ofp, "\" %% \\\n\t\t("); 17017e4b21b8STom Zanussi 17027e4b21b8STom Zanussi not_first = 0; 17037e4b21b8STom Zanussi count = 0; 17047e4b21b8STom Zanussi 17057e4b21b8STom Zanussi for (f = event->format.fields; f; f = f->next) { 17067e4b21b8STom Zanussi if (not_first++) 17077e4b21b8STom Zanussi fprintf(ofp, ", "); 17087e4b21b8STom Zanussi 17097e4b21b8STom Zanussi if (++count % 5 == 0) 17107e4b21b8STom Zanussi fprintf(ofp, "\n\t\t"); 17117e4b21b8STom Zanussi 1712*bb39ccb2STzvetomir Stoyanov (VMware) if (f->flags & TEP_FIELD_IS_FLAG) { 17137e4b21b8STom Zanussi if ((count - 1) % 5 != 0) { 17147e4b21b8STom Zanussi fprintf(ofp, "\n\t\t"); 17157e4b21b8STom Zanussi count = 4; 17167e4b21b8STom Zanussi } 17177e4b21b8STom Zanussi fprintf(ofp, "flag_str(\""); 17187e4b21b8STom Zanussi fprintf(ofp, "%s__%s\", ", event->system, 17197e4b21b8STom Zanussi event->name); 17207e4b21b8STom Zanussi fprintf(ofp, "\"%s\", %s)", f->name, 17217e4b21b8STom Zanussi f->name); 1722*bb39ccb2STzvetomir Stoyanov (VMware) } else if (f->flags & TEP_FIELD_IS_SYMBOLIC) { 17237e4b21b8STom Zanussi if ((count - 1) % 5 != 0) { 17247e4b21b8STom Zanussi fprintf(ofp, "\n\t\t"); 17257e4b21b8STom Zanussi count = 4; 17267e4b21b8STom Zanussi } 17277e4b21b8STom Zanussi fprintf(ofp, "symbol_str(\""); 17287e4b21b8STom Zanussi fprintf(ofp, "%s__%s\", ", event->system, 17297e4b21b8STom Zanussi event->name); 17307e4b21b8STom Zanussi fprintf(ofp, "\"%s\", %s)", f->name, 17317e4b21b8STom Zanussi f->name); 17327e4b21b8STom Zanussi } else 17337e4b21b8STom Zanussi fprintf(ofp, "%s", f->name); 17347e4b21b8STom Zanussi } 17357e4b21b8STom Zanussi 1736877cc639SJeremy Cline fprintf(ofp, "))\n\n"); 17370f5f5bcdSJoseph Schuchart 1738877cc639SJeremy Cline fprintf(ofp, "\t\tprint('Sample: {'+" 1739877cc639SJeremy Cline "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')\n\n"); 1740a6418605SArun Kalyanasundaram 17410f5f5bcdSJoseph Schuchart fprintf(ofp, "\t\tfor node in common_callchain:"); 17420f5f5bcdSJoseph Schuchart fprintf(ofp, "\n\t\t\tif 'sym' in node:"); 1743877cc639SJeremy Cline fprintf(ofp, "\n\t\t\t\tprint(\"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name']))"); 17440f5f5bcdSJoseph Schuchart fprintf(ofp, "\n\t\t\telse:"); 1745877cc639SJeremy Cline fprintf(ofp, "\n\t\t\t\tprint(\"\t[%%x]\" %% (node['ip']))\n\n"); 1746877cc639SJeremy Cline fprintf(ofp, "\t\tprint()\n\n"); 17470f5f5bcdSJoseph Schuchart 17487e4b21b8STom Zanussi } 17497e4b21b8STom Zanussi 17507e4b21b8STom Zanussi fprintf(ofp, "def trace_unhandled(event_name, context, " 1751a6418605SArun Kalyanasundaram "event_fields_dict, perf_sample_dict):\n"); 17527e4b21b8STom Zanussi 1753877cc639SJeremy Cline fprintf(ofp, "\t\tprint(get_dict_as_string(event_fields_dict))\n"); 1754877cc639SJeremy Cline fprintf(ofp, "\t\tprint('Sample: {'+" 1755877cc639SJeremy Cline "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')\n\n"); 17567e4b21b8STom Zanussi 17577e4b21b8STom Zanussi fprintf(ofp, "def print_header(" 17587e4b21b8STom Zanussi "event_name, cpu, secs, nsecs, pid, comm):\n" 1759877cc639SJeremy Cline "\tprint(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" 1760877cc639SJeremy Cline "(event_name, cpu, secs, nsecs, pid, comm), end=\"\")\n\n"); 1761a6418605SArun Kalyanasundaram 1762a6418605SArun Kalyanasundaram fprintf(ofp, "def get_dict_as_string(a_dict, delimiter=' '):\n" 1763a6418605SArun Kalyanasundaram "\treturn delimiter.join" 1764a6418605SArun Kalyanasundaram "(['%%s=%%s'%%(k,str(v))for k,v in sorted(a_dict.items())])\n"); 17657e4b21b8STom Zanussi 17667e4b21b8STom Zanussi fclose(ofp); 17677e4b21b8STom Zanussi 17687e4b21b8STom Zanussi fprintf(stderr, "generated Python script: %s\n", fname); 17697e4b21b8STom Zanussi 17707e4b21b8STom Zanussi return 0; 17717e4b21b8STom Zanussi } 17727e4b21b8STom Zanussi 17737e4b21b8STom Zanussi struct scripting_ops python_scripting_ops = { 17747e4b21b8STom Zanussi .name = "Python", 17757e4b21b8STom Zanussi .start_script = python_start_script, 1776d445dd2aSAdrian Hunter .flush_script = python_flush_script, 17777e4b21b8STom Zanussi .stop_script = python_stop_script, 17787e4b21b8STom Zanussi .process_event = python_process_event, 1779aef90263SJiri Olsa .process_stat = python_process_stat, 1780aef90263SJiri Olsa .process_stat_interval = python_process_stat_interval, 17817e4b21b8STom Zanussi .generate_script = python_generate_script, 17827e4b21b8STom Zanussi }; 1783