1 // tracecmd.i 2 %module ctracecmd 3 %include "typemaps.i" 4 %include "constraints.i" 5 6 %nodefaultctor record; 7 %nodefaultdtor record; 8 9 %apply Pointer NONNULL { struct tracecmd_input *handle }; 10 %apply Pointer NONNULL { struct tep_handle *pevent }; 11 %apply Pointer NONNULL { struct tep_format_field * }; 12 %apply unsigned long long *OUTPUT {unsigned long long *} 13 %apply int *OUTPUT {int *} 14 15 16 %{ 17 #include "trace-cmd.h" 18 #include "event-parse.h" 19 #include "event-utils.h" 20 #include <Python.h> 21 %} 22 23 24 %typemap(in) PyObject *pyfunc { 25 if (!PyCallable_Check($input)) { 26 PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 27 return NULL; 28 } 29 $1 = $input; 30 } 31 32 %ignore python_callback; 33 34 %inline %{ 35 static int python_callback(struct trace_seq *s, 36 struct tep_record *record, 37 struct tep_event *event, 38 void *context); 39 40 static int skip_output = 0; 41 42 static void py_supress_trace_output(void) 43 { 44 skip_output = 1; 45 } 46 47 void warning(const char *fmt, ...) 48 { 49 va_list ap; 50 51 if (skip_output) 52 return; 53 54 va_start(ap, fmt); 55 tep_vprint("tracecmd", TEP_LOG_WARNING, true, fmt, ap); 56 va_end(ap); 57 } 58 59 PyObject *convert_pevent(unsigned long pevent) 60 { 61 void *pev = (void *)pevent; 62 return SWIG_NewPointerObj(SWIG_as_voidptr(pev), SWIGTYPE_p_tep_handle, 0); 63 } 64 65 void py_pevent_register_event_handler(struct tep_handle *pevent, int id, 66 char *subsys, char *evname, 67 PyObject *pyfunc) 68 { 69 Py_INCREF(pyfunc); 70 tep_register_event_handler(pevent, id, subsys, evname, 71 python_callback, pyfunc); 72 } 73 74 static PyObject *py_field_get_stack(struct tep_handle *pevent, 75 struct tep_record *record, 76 struct tep_event *event, 77 int long_size) 78 { 79 PyObject *list; 80 struct tep_format_field *field; 81 void *data = record->data; 82 const char *func = NULL; 83 unsigned long addr; 84 85 field = tep_find_any_field(event, "caller"); 86 if (!field) { 87 PyErr_SetString(PyExc_TypeError, 88 "Event doesn't have caller field"); 89 return NULL; 90 } 91 92 list = PyList_New(0); 93 94 for (data += field->offset; data < record->data + record->size; 95 data += long_size) { 96 addr = tep_read_number(event->tep, data, long_size); 97 98 if ((long_size == 8 && addr == (unsigned long long)-1) || 99 ((int)addr == -1)) 100 break; 101 func = tep_find_function(event->tep, addr); 102 if (PyList_Append(list, PyUnicode_FromString(func))) { 103 Py_DECREF(list); 104 return NULL; 105 } 106 } 107 108 return list; 109 } 110 111 #if PY_MAJOR_VERSION >= 3 112 static PyObject *fromMemory(void *buf, size_t len) 113 { 114 return PyMemoryView_FromMemory(buf, len, PyBUF_READ); 115 } 116 #define PY_INT_AS_LONG PyLong_AsLong 117 #else 118 static PyObject *fromMemory(void *buf, size_t len) 119 { 120 return PyBuffer_FromMemory(buf, len); 121 } 122 #define PY_INT_AS_LONG PyInt_AS_LONG 123 #endif 124 125 126 127 static PyObject *py_field_get_data(struct tep_format_field *f, struct tep_record *r) 128 { 129 if (!strncmp(f->type, "__data_loc ", 11)) { 130 unsigned long long val; 131 int len, offset; 132 133 if (tep_read_number_field(f, r->data, &val)) { 134 PyErr_SetString(PyExc_TypeError, 135 "Field is not a valid number"); 136 return NULL; 137 } 138 139 /* 140 * The actual length of the dynamic array is stored 141 * in the top half of the field, and the offset 142 * is in the bottom half of the 32 bit field. 143 */ 144 offset = val & 0xffff; 145 len = val >> 16; 146 147 return fromMemory(r->data + offset, len); 148 } 149 150 return fromMemory(r->data + f->offset, f->size); 151 } 152 153 static PyObject *py_field_get_str(struct tep_format_field *f, struct tep_record *r) 154 { 155 if (!strncmp(f->type, "__data_loc ", 11)) { 156 unsigned long long val; 157 int offset; 158 159 if (tep_read_number_field(f, r->data, &val)) { 160 PyErr_SetString(PyExc_TypeError, 161 "Field is not a valid number"); 162 return NULL; 163 } 164 165 /* 166 * The actual length of the dynamic array is stored 167 * in the top half of the field, and the offset 168 * is in the bottom half of the 32 bit field. 169 */ 170 offset = val & 0xffff; 171 172 return PyUnicode_FromString((char *)r->data + offset); 173 } 174 175 return PyUnicode_FromStringAndSize((char *)r->data + f->offset, 176 strnlen((char *)r->data + f->offset, f->size)); 177 } 178 179 static PyObject *py_format_get_keys(struct tep_event *ef) 180 { 181 PyObject *list; 182 struct tep_format_field *f; 183 184 list = PyList_New(0); 185 186 for (f = ef->format.fields; f; f = f->next) { 187 if (PyList_Append(list, PyUnicode_FromString(f->name))) { 188 Py_DECREF(list); 189 return NULL; 190 } 191 } 192 193 return list; 194 } 195 %} 196 197 198 %wrapper %{ 199 static int python_callback(struct trace_seq *s, 200 struct tep_record *record, 201 struct tep_event *event, 202 void *context) 203 { 204 PyObject *arglist, *result; 205 int r = 0; 206 207 record->ref_count++; 208 209 arglist = Py_BuildValue("(OOO)", 210 SWIG_NewPointerObj(SWIG_as_voidptr(s), 211 SWIGTYPE_p_trace_seq, 0), 212 SWIG_NewPointerObj(SWIG_as_voidptr(record), 213 SWIGTYPE_p_tep_record, 0), 214 SWIG_NewPointerObj(SWIG_as_voidptr(event), 215 SWIGTYPE_p_tep_event, 0)); 216 217 result = PyEval_CallObject(context, arglist); 218 Py_XDECREF(arglist); 219 if (result && result != Py_None) { 220 if (!PyInt_Check(result)) { 221 PyErr_SetString(PyExc_TypeError, 222 "callback must return int"); 223 PyErr_Print(); 224 Py_XDECREF(result); 225 return 0; 226 } 227 r = PY_INT_AS_LONG(result); 228 } else if (result == Py_None) 229 r = 0; 230 else 231 PyErr_Print(); 232 233 Py_XDECREF(result); 234 235 return r; 236 } 237 %} 238 239 240 %ignore trace_seq_vprintf; 241 %ignore vpr_stat; 242 243 /* SWIG can't grok these, define them to nothing */ 244 #define __trace 245 #define __attribute__(x) 246 #define __thread 247 248 %include "trace-cmd.h" 249 %include <trace-seq.h> 250 %include <event-parse.h> 251