aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c302
1 files changed, 220 insertions, 82 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 1c419321f707..496f21cadd97 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -27,11 +27,14 @@
27#include <errno.h> 27#include <errno.h>
28 28
29#include "../../perf.h" 29#include "../../perf.h"
30#include "../debug.h"
31#include "../callchain.h"
30#include "../evsel.h" 32#include "../evsel.h"
31#include "../util.h" 33#include "../util.h"
32#include "../event.h" 34#include "../event.h"
33#include "../thread.h" 35#include "../thread.h"
34#include "../trace-event.h" 36#include "../trace-event.h"
37#include "../machine.h"
35 38
36PyMODINIT_FUNC initperf_trace_context(void); 39PyMODINIT_FUNC initperf_trace_context(void);
37 40
@@ -50,10 +53,14 @@ static int zero_flag_atom;
50 53
51static PyObject *main_module, *main_dict; 54static PyObject *main_module, *main_dict;
52 55
56static void handler_call_die(const char *handler_name) NORETURN;
53static void handler_call_die(const char *handler_name) 57static void handler_call_die(const char *handler_name)
54{ 58{
55 PyErr_Print(); 59 PyErr_Print();
56 Py_FatalError("problem in Python trace event handler"); 60 Py_FatalError("problem in Python trace event handler");
61 // Py_FatalError does not return
62 // but we have to make the compiler happy
63 abort();
57} 64}
58 65
59/* 66/*
@@ -67,6 +74,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj
67 Py_DECREF(val); 74 Py_DECREF(val);
68} 75}
69 76
77static PyObject *get_handler(const char *handler_name)
78{
79 PyObject *handler;
80
81 handler = PyDict_GetItemString(main_dict, handler_name);
82 if (handler && !PyCallable_Check(handler))
83 return NULL;
84 return handler;
85}
86
87static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
88{
89 PyObject *retval;
90
91 retval = PyObject_CallObject(handler, args);
92 if (retval == NULL)
93 handler_call_die(die_msg);
94 Py_DECREF(retval);
95}
96
97static void try_call_object(const char *handler_name, PyObject *args)
98{
99 PyObject *handler;
100
101 handler = get_handler(handler_name);
102 if (handler)
103 call_object(handler, args, handler_name);
104}
105
70static void define_value(enum print_arg_type field_type, 106static void define_value(enum print_arg_type field_type,
71 const char *ev_name, 107 const char *ev_name,
72 const char *field_name, 108 const char *field_name,
@@ -74,7 +110,7 @@ static void define_value(enum print_arg_type field_type,
74 const char *field_str) 110 const char *field_str)
75{ 111{
76 const char *handler_name = "define_flag_value"; 112 const char *handler_name = "define_flag_value";
77 PyObject *handler, *t, *retval; 113 PyObject *t;
78 unsigned long long value; 114 unsigned long long value;
79 unsigned n = 0; 115 unsigned n = 0;
80 116
@@ -92,12 +128,7 @@ static void define_value(enum print_arg_type field_type,
92 PyTuple_SetItem(t, n++, PyInt_FromLong(value)); 128 PyTuple_SetItem(t, n++, PyInt_FromLong(value));
93 PyTuple_SetItem(t, n++, PyString_FromString(field_str)); 129 PyTuple_SetItem(t, n++, PyString_FromString(field_str));
94 130
95 handler = PyDict_GetItemString(main_dict, handler_name); 131 try_call_object(handler_name, t);
96 if (handler && PyCallable_Check(handler)) {
97 retval = PyObject_CallObject(handler, t);
98 if (retval == NULL)
99 handler_call_die(handler_name);
100 }
101 132
102 Py_DECREF(t); 133 Py_DECREF(t);
103} 134}
@@ -120,7 +151,7 @@ static void define_field(enum print_arg_type field_type,
120 const char *delim) 151 const char *delim)
121{ 152{
122 const char *handler_name = "define_flag_field"; 153 const char *handler_name = "define_flag_field";
123 PyObject *handler, *t, *retval; 154 PyObject *t;
124 unsigned n = 0; 155 unsigned n = 0;
125 156
126 if (field_type == PRINT_SYMBOL) 157 if (field_type == PRINT_SYMBOL)
@@ -138,12 +169,7 @@ static void define_field(enum print_arg_type field_type,
138 if (field_type == PRINT_FLAGS) 169 if (field_type == PRINT_FLAGS)
139 PyTuple_SetItem(t, n++, PyString_FromString(delim)); 170 PyTuple_SetItem(t, n++, PyString_FromString(delim));
140 171
141 handler = PyDict_GetItemString(main_dict, handler_name); 172 try_call_object(handler_name, t);
142 if (handler && PyCallable_Check(handler)) {
143 retval = PyObject_CallObject(handler, t);
144 if (retval == NULL)
145 handler_call_die(handler_name);
146 }
147 173
148 Py_DECREF(t); 174 Py_DECREF(t);
149} 175}
@@ -231,15 +257,133 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
231 return event; 257 return event;
232} 258}
233 259
260static PyObject *get_field_numeric_entry(struct event_format *event,
261 struct format_field *field, void *data)
262{
263 bool is_array = field->flags & FIELD_IS_ARRAY;
264 PyObject *obj, *list = NULL;
265 unsigned long long val;
266 unsigned int item_size, n_items, i;
267
268 if (is_array) {
269 list = PyList_New(field->arraylen);
270 item_size = field->size / field->arraylen;
271 n_items = field->arraylen;
272 } else {
273 item_size = field->size;
274 n_items = 1;
275 }
276
277 for (i = 0; i < n_items; i++) {
278
279 val = read_size(event, data + field->offset + i * item_size,
280 item_size);
281 if (field->flags & FIELD_IS_SIGNED) {
282 if ((long long)val >= LONG_MIN &&
283 (long long)val <= LONG_MAX)
284 obj = PyInt_FromLong(val);
285 else
286 obj = PyLong_FromLongLong(val);
287 } else {
288 if (val <= LONG_MAX)
289 obj = PyInt_FromLong(val);
290 else
291 obj = PyLong_FromUnsignedLongLong(val);
292 }
293 if (is_array)
294 PyList_SET_ITEM(list, i, obj);
295 }
296 if (is_array)
297 obj = list;
298 return obj;
299}
300
301
302static PyObject *python_process_callchain(struct perf_sample *sample,
303 struct perf_evsel *evsel,
304 struct addr_location *al)
305{
306 PyObject *pylist;
307
308 pylist = PyList_New(0);
309 if (!pylist)
310 Py_FatalError("couldn't create Python list");
311
312 if (!symbol_conf.use_callchain || !sample->callchain)
313 goto exit;
314
315 if (machine__resolve_callchain(al->machine, evsel, al->thread,
316 sample, NULL, NULL,
317 PERF_MAX_STACK_DEPTH) != 0) {
318 pr_err("Failed to resolve callchain. Skipping\n");
319 goto exit;
320 }
321 callchain_cursor_commit(&callchain_cursor);
322
323
324 while (1) {
325 PyObject *pyelem;
326 struct callchain_cursor_node *node;
327 node = callchain_cursor_current(&callchain_cursor);
328 if (!node)
329 break;
330
331 pyelem = PyDict_New();
332 if (!pyelem)
333 Py_FatalError("couldn't create Python dictionary");
334
335
336 pydict_set_item_string_decref(pyelem, "ip",
337 PyLong_FromUnsignedLongLong(node->ip));
338
339 if (node->sym) {
340 PyObject *pysym = PyDict_New();
341 if (!pysym)
342 Py_FatalError("couldn't create Python dictionary");
343 pydict_set_item_string_decref(pysym, "start",
344 PyLong_FromUnsignedLongLong(node->sym->start));
345 pydict_set_item_string_decref(pysym, "end",
346 PyLong_FromUnsignedLongLong(node->sym->end));
347 pydict_set_item_string_decref(pysym, "binding",
348 PyInt_FromLong(node->sym->binding));
349 pydict_set_item_string_decref(pysym, "name",
350 PyString_FromStringAndSize(node->sym->name,
351 node->sym->namelen));
352 pydict_set_item_string_decref(pyelem, "sym", pysym);
353 }
354
355 if (node->map) {
356 struct map *map = node->map;
357 const char *dsoname = "[unknown]";
358 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
359 if (symbol_conf.show_kernel_path && map->dso->long_name)
360 dsoname = map->dso->long_name;
361 else if (map->dso->name)
362 dsoname = map->dso->name;
363 }
364 pydict_set_item_string_decref(pyelem, "dso",
365 PyString_FromString(dsoname));
366 }
367
368 callchain_cursor_advance(&callchain_cursor);
369 PyList_Append(pylist, pyelem);
370 Py_DECREF(pyelem);
371 }
372
373exit:
374 return pylist;
375}
376
377
234static void python_process_tracepoint(struct perf_sample *sample, 378static void python_process_tracepoint(struct perf_sample *sample,
235 struct perf_evsel *evsel, 379 struct perf_evsel *evsel,
236 struct thread *thread, 380 struct thread *thread,
237 struct addr_location *al) 381 struct addr_location *al)
238{ 382{
239 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 383 PyObject *handler, *context, *t, *obj, *callchain;
384 PyObject *dict = NULL;
240 static char handler_name[256]; 385 static char handler_name[256];
241 struct format_field *field; 386 struct format_field *field;
242 unsigned long long val;
243 unsigned long s, ns; 387 unsigned long s, ns;
244 struct event_format *event; 388 struct event_format *event;
245 unsigned n = 0; 389 unsigned n = 0;
@@ -261,9 +405,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
261 405
262 sprintf(handler_name, "%s__%s", event->system, event->name); 406 sprintf(handler_name, "%s__%s", event->system, event->name);
263 407
264 handler = PyDict_GetItemString(main_dict, handler_name); 408 handler = get_handler(handler_name);
265 if (handler && !PyCallable_Check(handler))
266 handler = NULL;
267 if (!handler) { 409 if (!handler) {
268 dict = PyDict_New(); 410 dict = PyDict_New();
269 if (!dict) 411 if (!dict)
@@ -280,18 +422,23 @@ static void python_process_tracepoint(struct perf_sample *sample,
280 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 422 PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
281 PyTuple_SetItem(t, n++, context); 423 PyTuple_SetItem(t, n++, context);
282 424
425 /* ip unwinding */
426 callchain = python_process_callchain(sample, evsel, al);
427
283 if (handler) { 428 if (handler) {
284 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 429 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
285 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 430 PyTuple_SetItem(t, n++, PyInt_FromLong(s));
286 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 431 PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
287 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 432 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
288 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 433 PyTuple_SetItem(t, n++, PyString_FromString(comm));
434 PyTuple_SetItem(t, n++, callchain);
289 } else { 435 } else {
290 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 436 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
291 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 437 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
292 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 438 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
293 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 439 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
294 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); 440 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
441 pydict_set_item_string_decref(dict, "common_callchain", callchain);
295 } 442 }
296 for (field = event->format.fields; field; field = field->next) { 443 for (field = event->format.fields; field; field = field->next) {
297 if (field->flags & FIELD_IS_STRING) { 444 if (field->flags & FIELD_IS_STRING) {
@@ -303,20 +450,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
303 offset = field->offset; 450 offset = field->offset;
304 obj = PyString_FromString((char *)data + offset); 451 obj = PyString_FromString((char *)data + offset);
305 } else { /* FIELD_IS_NUMERIC */ 452 } else { /* FIELD_IS_NUMERIC */
306 val = read_size(event, data + field->offset, 453 obj = get_field_numeric_entry(event, field, data);
307 field->size);
308 if (field->flags & FIELD_IS_SIGNED) {
309 if ((long long)val >= LONG_MIN &&
310 (long long)val <= LONG_MAX)
311 obj = PyInt_FromLong(val);
312 else
313 obj = PyLong_FromLongLong(val);
314 } else {
315 if (val <= LONG_MAX)
316 obj = PyInt_FromLong(val);
317 else
318 obj = PyLong_FromUnsignedLongLong(val);
319 }
320 } 454 }
321 if (handler) 455 if (handler)
322 PyTuple_SetItem(t, n++, obj); 456 PyTuple_SetItem(t, n++, obj);
@@ -324,6 +458,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
324 pydict_set_item_string_decref(dict, field->name, obj); 458 pydict_set_item_string_decref(dict, field->name, obj);
325 459
326 } 460 }
461
327 if (!handler) 462 if (!handler)
328 PyTuple_SetItem(t, n++, dict); 463 PyTuple_SetItem(t, n++, dict);
329 464
@@ -331,17 +466,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
331 Py_FatalError("error resizing Python tuple"); 466 Py_FatalError("error resizing Python tuple");
332 467
333 if (handler) { 468 if (handler) {
334 retval = PyObject_CallObject(handler, t); 469 call_object(handler, t, handler_name);
335 if (retval == NULL)
336 handler_call_die(handler_name);
337 } else { 470 } else {
338 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 471 try_call_object("trace_unhandled", t);
339 if (handler && PyCallable_Check(handler)) {
340
341 retval = PyObject_CallObject(handler, t);
342 if (retval == NULL)
343 handler_call_die("trace_unhandled");
344 }
345 Py_DECREF(dict); 472 Py_DECREF(dict);
346 } 473 }
347 474
@@ -353,7 +480,7 @@ static void python_process_general_event(struct perf_sample *sample,
353 struct thread *thread, 480 struct thread *thread,
354 struct addr_location *al) 481 struct addr_location *al)
355{ 482{
356 PyObject *handler, *retval, *t, *dict; 483 PyObject *handler, *t, *dict, *callchain, *dict_sample;
357 static char handler_name[64]; 484 static char handler_name[64];
358 unsigned n = 0; 485 unsigned n = 0;
359 486
@@ -369,17 +496,34 @@ static void python_process_general_event(struct perf_sample *sample,
369 if (!dict) 496 if (!dict)
370 Py_FatalError("couldn't create Python dictionary"); 497 Py_FatalError("couldn't create Python dictionary");
371 498
499 dict_sample = PyDict_New();
500 if (!dict_sample)
501 Py_FatalError("couldn't create Python dictionary");
502
372 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 503 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
373 504
374 handler = PyDict_GetItemString(main_dict, handler_name); 505 handler = get_handler(handler_name);
375 if (!handler || !PyCallable_Check(handler)) 506 if (!handler)
376 goto exit; 507 goto exit;
377 508
378 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 509 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
379 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( 510 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
380 (const char *)&evsel->attr, sizeof(evsel->attr))); 511 (const char *)&evsel->attr, sizeof(evsel->attr)));
381 pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize( 512
382 (const char *)sample, sizeof(*sample))); 513 pydict_set_item_string_decref(dict_sample, "pid",
514 PyInt_FromLong(sample->pid));
515 pydict_set_item_string_decref(dict_sample, "tid",
516 PyInt_FromLong(sample->tid));
517 pydict_set_item_string_decref(dict_sample, "cpu",
518 PyInt_FromLong(sample->cpu));
519 pydict_set_item_string_decref(dict_sample, "ip",
520 PyLong_FromUnsignedLongLong(sample->ip));
521 pydict_set_item_string_decref(dict_sample, "time",
522 PyLong_FromUnsignedLongLong(sample->time));
523 pydict_set_item_string_decref(dict_sample, "period",
524 PyLong_FromUnsignedLongLong(sample->period));
525 pydict_set_item_string_decref(dict, "sample", dict_sample);
526
383 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( 527 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
384 (const char *)sample->raw_data, sample->raw_size)); 528 (const char *)sample->raw_data, sample->raw_size));
385 pydict_set_item_string_decref(dict, "comm", 529 pydict_set_item_string_decref(dict, "comm",
@@ -393,13 +537,15 @@ static void python_process_general_event(struct perf_sample *sample,
393 PyString_FromString(al->sym->name)); 537 PyString_FromString(al->sym->name));
394 } 538 }
395 539
540 /* ip unwinding */
541 callchain = python_process_callchain(sample, evsel, al);
542 pydict_set_item_string_decref(dict, "callchain", callchain);
543
396 PyTuple_SetItem(t, n++, dict); 544 PyTuple_SetItem(t, n++, dict);
397 if (_PyTuple_Resize(&t, n) == -1) 545 if (_PyTuple_Resize(&t, n) == -1)
398 Py_FatalError("error resizing Python tuple"); 546 Py_FatalError("error resizing Python tuple");
399 547
400 retval = PyObject_CallObject(handler, t); 548 call_object(handler, t, handler_name);
401 if (retval == NULL)
402 handler_call_die(handler_name);
403exit: 549exit:
404 Py_DECREF(dict); 550 Py_DECREF(dict);
405 Py_DECREF(t); 551 Py_DECREF(t);
@@ -423,36 +569,24 @@ static void python_process_event(union perf_event *event __maybe_unused,
423 569
424static int run_start_sub(void) 570static int run_start_sub(void)
425{ 571{
426 PyObject *handler, *retval;
427 int err = 0;
428
429 main_module = PyImport_AddModule("__main__"); 572 main_module = PyImport_AddModule("__main__");
430 if (main_module == NULL) 573 if (main_module == NULL)
431 return -1; 574 return -1;
432 Py_INCREF(main_module); 575 Py_INCREF(main_module);
433 576
434 main_dict = PyModule_GetDict(main_module); 577 main_dict = PyModule_GetDict(main_module);
435 if (main_dict == NULL) { 578 if (main_dict == NULL)
436 err = -1;
437 goto error; 579 goto error;
438 }
439 Py_INCREF(main_dict); 580 Py_INCREF(main_dict);
440 581
441 handler = PyDict_GetItemString(main_dict, "trace_begin"); 582 try_call_object("trace_begin", NULL);
442 if (handler == NULL || !PyCallable_Check(handler))
443 goto out;
444 583
445 retval = PyObject_CallObject(handler, NULL); 584 return 0;
446 if (retval == NULL)
447 handler_call_die("trace_begin");
448 585
449 Py_DECREF(retval);
450 return err;
451error: 586error:
452 Py_XDECREF(main_dict); 587 Py_XDECREF(main_dict);
453 Py_XDECREF(main_module); 588 Py_XDECREF(main_module);
454out: 589 return -1;
455 return err;
456} 590}
457 591
458/* 592/*
@@ -506,29 +640,23 @@ error:
506 return err; 640 return err;
507} 641}
508 642
643static int python_flush_script(void)
644{
645 return 0;
646}
647
509/* 648/*
510 * Stop trace script 649 * Stop trace script
511 */ 650 */
512static int python_stop_script(void) 651static int python_stop_script(void)
513{ 652{
514 PyObject *handler, *retval; 653 try_call_object("trace_end", NULL);
515 int err = 0;
516
517 handler = PyDict_GetItemString(main_dict, "trace_end");
518 if (handler == NULL || !PyCallable_Check(handler))
519 goto out;
520 654
521 retval = PyObject_CallObject(handler, NULL);
522 if (retval == NULL)
523 handler_call_die("trace_end");
524 else
525 Py_DECREF(retval);
526out:
527 Py_XDECREF(main_dict); 655 Py_XDECREF(main_dict);
528 Py_XDECREF(main_module); 656 Py_XDECREF(main_module);
529 Py_Finalize(); 657 Py_Finalize();
530 658
531 return err; 659 return 0;
532} 660}
533 661
534static int python_generate_script(struct pevent *pevent, const char *outfile) 662static int python_generate_script(struct pevent *pevent, const char *outfile)
@@ -589,6 +717,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
589 fprintf(ofp, "common_nsecs, "); 717 fprintf(ofp, "common_nsecs, ");
590 fprintf(ofp, "common_pid, "); 718 fprintf(ofp, "common_pid, ");
591 fprintf(ofp, "common_comm,\n\t"); 719 fprintf(ofp, "common_comm,\n\t");
720 fprintf(ofp, "common_callchain, ");
592 721
593 not_first = 0; 722 not_first = 0;
594 count = 0; 723 count = 0;
@@ -632,7 +761,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
632 fprintf(ofp, "%%u"); 761 fprintf(ofp, "%%u");
633 } 762 }
634 763
635 fprintf(ofp, "\\n\" %% \\\n\t\t("); 764 fprintf(ofp, "\" %% \\\n\t\t(");
636 765
637 not_first = 0; 766 not_first = 0;
638 count = 0; 767 count = 0;
@@ -668,7 +797,15 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
668 fprintf(ofp, "%s", f->name); 797 fprintf(ofp, "%s", f->name);
669 } 798 }
670 799
671 fprintf(ofp, "),\n\n"); 800 fprintf(ofp, ")\n\n");
801
802 fprintf(ofp, "\t\tfor node in common_callchain:");
803 fprintf(ofp, "\n\t\t\tif 'sym' in node:");
804 fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])");
805 fprintf(ofp, "\n\t\t\telse:");
806 fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
807 fprintf(ofp, "\t\tprint \"\\n\"\n\n");
808
672 } 809 }
673 810
674 fprintf(ofp, "def trace_unhandled(event_name, context, " 811 fprintf(ofp, "def trace_unhandled(event_name, context, "
@@ -692,6 +829,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
692struct scripting_ops python_scripting_ops = { 829struct scripting_ops python_scripting_ops = {
693 .name = "Python", 830 .name = "Python",
694 .start_script = python_start_script, 831 .start_script = python_start_script,
832 .flush_script = python_flush_script,
695 .stop_script = python_stop_script, 833 .stop_script = python_stop_script,
696 .process_event = python_process_event, 834 .process_event = python_process_event,
697 .generate_script = python_generate_script, 835 .generate_script = python_generate_script,