linux/tools/perf/util/scripting-engines/trace-event-python.c
<<
>>
Prefs
   1/*
   2 * trace-event-python.  Feed trace events to an embedded Python interpreter.
   3 *
   4 * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 */
  21
  22#include <Python.h>
  23
  24#include <stdio.h>
  25#include <stdlib.h>
  26#include <string.h>
  27#include <stdbool.h>
  28#include <errno.h>
  29#include <linux/bitmap.h>
  30
  31#include "../../perf.h"
  32#include "../debug.h"
  33#include "../callchain.h"
  34#include "../evsel.h"
  35#include "../util.h"
  36#include "../event.h"
  37#include "../thread.h"
  38#include "../comm.h"
  39#include "../machine.h"
  40#include "../db-export.h"
  41#include "../thread-stack.h"
  42#include "../trace-event.h"
  43#include "../machine.h"
  44#include "../call-path.h"
  45#include "thread_map.h"
  46#include "cpumap.h"
  47#include "stat.h"
  48
  49PyMODINIT_FUNC initperf_trace_context(void);
  50
  51#define TRACE_EVENT_TYPE_MAX                            \
  52        ((1 << (sizeof(unsigned short) * 8)) - 1)
  53
  54static DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX);
  55
  56#define MAX_FIELDS      64
  57#define N_COMMON_FIELDS 7
  58
  59extern struct scripting_context *scripting_context;
  60
  61static char *cur_field_name;
  62static int zero_flag_atom;
  63
  64static PyObject *main_module, *main_dict;
  65
  66struct tables {
  67        struct db_export        dbe;
  68        PyObject                *evsel_handler;
  69        PyObject                *machine_handler;
  70        PyObject                *thread_handler;
  71        PyObject                *comm_handler;
  72        PyObject                *comm_thread_handler;
  73        PyObject                *dso_handler;
  74        PyObject                *symbol_handler;
  75        PyObject                *branch_type_handler;
  76        PyObject                *sample_handler;
  77        PyObject                *call_path_handler;
  78        PyObject                *call_return_handler;
  79        bool                    db_export_mode;
  80};
  81
  82static struct tables tables_global;
  83
  84static void handler_call_die(const char *handler_name) NORETURN;
  85static void handler_call_die(const char *handler_name)
  86{
  87        PyErr_Print();
  88        Py_FatalError("problem in Python trace event handler");
  89        // Py_FatalError does not return
  90        // but we have to make the compiler happy
  91        abort();
  92}
  93
  94/*
  95 * Insert val into into the dictionary and decrement the reference counter.
  96 * This is necessary for dictionaries since PyDict_SetItemString() does not
  97 * steal a reference, as opposed to PyTuple_SetItem().
  98 */
  99static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val)
 100{
 101        PyDict_SetItemString(dict, key, val);
 102        Py_DECREF(val);
 103}
 104
 105static PyObject *get_handler(const char *handler_name)
 106{
 107        PyObject *handler;
 108
 109        handler = PyDict_GetItemString(main_dict, handler_name);
 110        if (handler && !PyCallable_Check(handler))
 111                return NULL;
 112        return handler;
 113}
 114
 115static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
 116{
 117        PyObject *retval;
 118
 119        retval = PyObject_CallObject(handler, args);
 120        if (retval == NULL)
 121                handler_call_die(die_msg);
 122        Py_DECREF(retval);
 123}
 124
 125static void try_call_object(const char *handler_name, PyObject *args)
 126{
 127        PyObject *handler;
 128
 129        handler = get_handler(handler_name);
 130        if (handler)
 131                call_object(handler, args, handler_name);
 132}
 133
 134static void define_value(enum print_arg_type field_type,
 135                         const char *ev_name,
 136                         const char *field_name,
 137                         const char *field_value,
 138                         const char *field_str)
 139{
 140        const char *handler_name = "define_flag_value";
 141        PyObject *t;
 142        unsigned long long value;
 143        unsigned n = 0;
 144
 145        if (field_type == PRINT_SYMBOL)
 146                handler_name = "define_symbolic_value";
 147
 148        t = PyTuple_New(4);
 149        if (!t)
 150                Py_FatalError("couldn't create Python tuple");
 151
 152        value = eval_flag(field_value);
 153
 154        PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
 155        PyTuple_SetItem(t, n++, PyString_FromString(field_name));
 156        PyTuple_SetItem(t, n++, PyInt_FromLong(value));
 157        PyTuple_SetItem(t, n++, PyString_FromString(field_str));
 158
 159        try_call_object(handler_name, t);
 160
 161        Py_DECREF(t);
 162}
 163
 164static void define_values(enum print_arg_type field_type,
 165                          struct print_flag_sym *field,
 166                          const char *ev_name,
 167                          const char *field_name)
 168{
 169        define_value(field_type, ev_name, field_name, field->value,
 170                     field->str);
 171
 172        if (field->next)
 173                define_values(field_type, field->next, ev_name, field_name);
 174}
 175
 176static void define_field(enum print_arg_type field_type,
 177                         const char *ev_name,
 178                         const char *field_name,
 179                         const char *delim)
 180{
 181        const char *handler_name = "define_flag_field";
 182        PyObject *t;
 183        unsigned n = 0;
 184
 185        if (field_type == PRINT_SYMBOL)
 186                handler_name = "define_symbolic_field";
 187
 188        if (field_type == PRINT_FLAGS)
 189                t = PyTuple_New(3);
 190        else
 191                t = PyTuple_New(2);
 192        if (!t)
 193                Py_FatalError("couldn't create Python tuple");
 194
 195        PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
 196        PyTuple_SetItem(t, n++, PyString_FromString(field_name));
 197        if (field_type == PRINT_FLAGS)
 198                PyTuple_SetItem(t, n++, PyString_FromString(delim));
 199
 200        try_call_object(handler_name, t);
 201
 202        Py_DECREF(t);
 203}
 204
 205static void define_event_symbols(struct event_format *event,
 206                                 const char *ev_name,
 207                                 struct print_arg *args)
 208{
 209        if (args == NULL)
 210                return;
 211
 212        switch (args->type) {
 213        case PRINT_NULL:
 214                break;
 215        case PRINT_ATOM:
 216                define_value(PRINT_FLAGS, ev_name, cur_field_name, "0",
 217                             args->atom.atom);
 218                zero_flag_atom = 0;
 219                break;
 220        case PRINT_FIELD:
 221                free(cur_field_name);
 222                cur_field_name = strdup(args->field.name);
 223                break;
 224        case PRINT_FLAGS:
 225                define_event_symbols(event, ev_name, args->flags.field);
 226                define_field(PRINT_FLAGS, ev_name, cur_field_name,
 227                             args->flags.delim);
 228                define_values(PRINT_FLAGS, args->flags.flags, ev_name,
 229                              cur_field_name);
 230                break;
 231        case PRINT_SYMBOL:
 232                define_event_symbols(event, ev_name, args->symbol.field);
 233                define_field(PRINT_SYMBOL, ev_name, cur_field_name, NULL);
 234                define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name,
 235                              cur_field_name);
 236                break;
 237        case PRINT_HEX:
 238                define_event_symbols(event, ev_name, args->hex.field);
 239                define_event_symbols(event, ev_name, args->hex.size);
 240                break;
 241        case PRINT_INT_ARRAY:
 242                define_event_symbols(event, ev_name, args->int_array.field);
 243                define_event_symbols(event, ev_name, args->int_array.count);
 244                define_event_symbols(event, ev_name, args->int_array.el_size);
 245                break;
 246        case PRINT_STRING:
 247                break;
 248        case PRINT_TYPE:
 249                define_event_symbols(event, ev_name, args->typecast.item);
 250                break;
 251        case PRINT_OP:
 252                if (strcmp(args->op.op, ":") == 0)
 253                        zero_flag_atom = 1;
 254                define_event_symbols(event, ev_name, args->op.left);
 255                define_event_symbols(event, ev_name, args->op.right);
 256                break;
 257        default:
 258                /* gcc warns for these? */
 259        case PRINT_BSTRING:
 260        case PRINT_DYNAMIC_ARRAY:
 261        case PRINT_DYNAMIC_ARRAY_LEN:
 262        case PRINT_FUNC:
 263        case PRINT_BITMASK:
 264                /* we should warn... */
 265                return;
 266        }
 267
 268        if (args->next)
 269                define_event_symbols(event, ev_name, args->next);
 270}
 271
 272static PyObject *get_field_numeric_entry(struct event_format *event,
 273                struct format_field *field, void *data)
 274{
 275        bool is_array = field->flags & FIELD_IS_ARRAY;
 276        PyObject *obj = NULL, *list = NULL;
 277        unsigned long long val;
 278        unsigned int item_size, n_items, i;
 279
 280        if (is_array) {
 281                list = PyList_New(field->arraylen);
 282                item_size = field->size / field->arraylen;
 283                n_items = field->arraylen;
 284        } else {
 285                item_size = field->size;
 286                n_items = 1;
 287        }
 288
 289        for (i = 0; i < n_items; i++) {
 290
 291                val = read_size(event, data + field->offset + i * item_size,
 292                                item_size);
 293                if (field->flags & FIELD_IS_SIGNED) {
 294                        if ((long long)val >= LONG_MIN &&
 295                                        (long long)val <= LONG_MAX)
 296                                obj = PyInt_FromLong(val);
 297                        else
 298                                obj = PyLong_FromLongLong(val);
 299                } else {
 300                        if (val <= LONG_MAX)
 301                                obj = PyInt_FromLong(val);
 302                        else
 303                                obj = PyLong_FromUnsignedLongLong(val);
 304                }
 305                if (is_array)
 306                        PyList_SET_ITEM(list, i, obj);
 307        }
 308        if (is_array)
 309                obj = list;
 310        return obj;
 311}
 312
 313
 314static PyObject *python_process_callchain(struct perf_sample *sample,
 315                                         struct perf_evsel *evsel,
 316                                         struct addr_location *al)
 317{
 318        PyObject *pylist;
 319
 320        pylist = PyList_New(0);
 321        if (!pylist)
 322                Py_FatalError("couldn't create Python list");
 323
 324        if (!symbol_conf.use_callchain || !sample->callchain)
 325                goto exit;
 326
 327        if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
 328                                      sample, NULL, NULL,
 329                                      scripting_max_stack) != 0) {
 330                pr_err("Failed to resolve callchain. Skipping\n");
 331                goto exit;
 332        }
 333        callchain_cursor_commit(&callchain_cursor);
 334
 335
 336        while (1) {
 337                PyObject *pyelem;
 338                struct callchain_cursor_node *node;
 339                node = callchain_cursor_current(&callchain_cursor);
 340                if (!node)
 341                        break;
 342
 343                pyelem = PyDict_New();
 344                if (!pyelem)
 345                        Py_FatalError("couldn't create Python dictionary");
 346
 347
 348                pydict_set_item_string_decref(pyelem, "ip",
 349                                PyLong_FromUnsignedLongLong(node->ip));
 350
 351                if (node->sym) {
 352                        PyObject *pysym  = PyDict_New();
 353                        if (!pysym)
 354                                Py_FatalError("couldn't create Python dictionary");
 355                        pydict_set_item_string_decref(pysym, "start",
 356                                        PyLong_FromUnsignedLongLong(node->sym->start));
 357                        pydict_set_item_string_decref(pysym, "end",
 358                                        PyLong_FromUnsignedLongLong(node->sym->end));
 359                        pydict_set_item_string_decref(pysym, "binding",
 360                                        PyInt_FromLong(node->sym->binding));
 361                        pydict_set_item_string_decref(pysym, "name",
 362                                        PyString_FromStringAndSize(node->sym->name,
 363                                                        node->sym->namelen));
 364                        pydict_set_item_string_decref(pyelem, "sym", pysym);
 365                }
 366
 367                if (node->map) {
 368                        struct map *map = node->map;
 369                        const char *dsoname = "[unknown]";
 370                        if (map && map->dso && (map->dso->name || map->dso->long_name)) {
 371                                if (symbol_conf.show_kernel_path && map->dso->long_name)
 372                                        dsoname = map->dso->long_name;
 373                                else if (map->dso->name)
 374                                        dsoname = map->dso->name;
 375                        }
 376                        pydict_set_item_string_decref(pyelem, "dso",
 377                                        PyString_FromString(dsoname));
 378                }
 379
 380                callchain_cursor_advance(&callchain_cursor);
 381                PyList_Append(pylist, pyelem);
 382                Py_DECREF(pyelem);
 383        }
 384
 385exit:
 386        return pylist;
 387}
 388
 389static void python_process_tracepoint(struct perf_sample *sample,
 390                                      struct perf_evsel *evsel,
 391                                      struct addr_location *al)
 392{
 393        struct event_format *event = evsel->tp_format;
 394        PyObject *handler, *context, *t, *obj = NULL, *callchain;
 395        PyObject *dict = NULL;
 396        static char handler_name[256];
 397        struct format_field *field;
 398        unsigned long s, ns;
 399        unsigned n = 0;
 400        int pid;
 401        int cpu = sample->cpu;
 402        void *data = sample->raw_data;
 403        unsigned long long nsecs = sample->time;
 404        const char *comm = thread__comm_str(al->thread);
 405
 406        t = PyTuple_New(MAX_FIELDS);
 407        if (!t)
 408                Py_FatalError("couldn't create Python tuple");
 409
 410        if (!event) {
 411                snprintf(handler_name, sizeof(handler_name),
 412                         "ug! no event found for type %" PRIu64, (u64)evsel->attr.config);
 413                Py_FatalError(handler_name);
 414        }
 415
 416        pid = raw_field_value(event, "common_pid", data);
 417
 418        sprintf(handler_name, "%s__%s", event->system, event->name);
 419
 420        if (!test_and_set_bit(event->id, events_defined))
 421                define_event_symbols(event, handler_name, event->print_fmt.args);
 422
 423        handler = get_handler(handler_name);
 424        if (!handler) {
 425                dict = PyDict_New();
 426                if (!dict)
 427                        Py_FatalError("couldn't create Python dict");
 428        }
 429        s = nsecs / NSECS_PER_SEC;
 430        ns = nsecs - s * NSECS_PER_SEC;
 431
 432        scripting_context->event_data = data;
 433        scripting_context->pevent = evsel->tp_format->pevent;
 434
 435        context = PyCObject_FromVoidPtr(scripting_context, NULL);
 436
 437        PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
 438        PyTuple_SetItem(t, n++, context);
 439
 440        /* ip unwinding */
 441        callchain = python_process_callchain(sample, evsel, al);
 442
 443        if (handler) {
 444                PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
 445                PyTuple_SetItem(t, n++, PyInt_FromLong(s));
 446                PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
 447                PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
 448                PyTuple_SetItem(t, n++, PyString_FromString(comm));
 449                PyTuple_SetItem(t, n++, callchain);
 450        } else {
 451                pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
 452                pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
 453                pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
 454                pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
 455                pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
 456                pydict_set_item_string_decref(dict, "common_callchain", callchain);
 457        }
 458        for (field = event->format.fields; field; field = field->next) {
 459                unsigned int offset, len;
 460                unsigned long long val;
 461
 462                if (field->flags & FIELD_IS_ARRAY) {
 463                        offset = field->offset;
 464                        len    = field->size;
 465                        if (field->flags & FIELD_IS_DYNAMIC) {
 466                                val     = pevent_read_number(scripting_context->pevent,
 467                                                             data + offset, len);
 468                                offset  = val;
 469                                len     = offset >> 16;
 470                                offset &= 0xffff;
 471                        }
 472                        if (field->flags & FIELD_IS_STRING &&
 473                            is_printable_array(data + offset, len)) {
 474                                obj = PyString_FromString((char *) data + offset);
 475                        } else {
 476                                obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
 477                                field->flags &= ~FIELD_IS_STRING;
 478                        }
 479                } else { /* FIELD_IS_NUMERIC */
 480                        obj = get_field_numeric_entry(event, field, data);
 481                }
 482                if (handler)
 483                        PyTuple_SetItem(t, n++, obj);
 484                else
 485                        pydict_set_item_string_decref(dict, field->name, obj);
 486
 487        }
 488
 489        if (!handler)
 490                PyTuple_SetItem(t, n++, dict);
 491
 492        if (_PyTuple_Resize(&t, n) == -1)
 493                Py_FatalError("error resizing Python tuple");
 494
 495        if (handler) {
 496                call_object(handler, t, handler_name);
 497        } else {
 498                try_call_object("trace_unhandled", t);
 499                Py_DECREF(dict);
 500        }
 501
 502        Py_DECREF(t);
 503}
 504
 505static PyObject *tuple_new(unsigned int sz)
 506{
 507        PyObject *t;
 508
 509        t = PyTuple_New(sz);
 510        if (!t)
 511                Py_FatalError("couldn't create Python tuple");
 512        return t;
 513}
 514
 515static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
 516{
 517#if BITS_PER_LONG == 64
 518        return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
 519#endif
 520#if BITS_PER_LONG == 32
 521        return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val));
 522#endif
 523}
 524
 525static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
 526{
 527        return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
 528}
 529
 530static int tuple_set_string(PyObject *t, unsigned int pos, const char *s)
 531{
 532        return PyTuple_SetItem(t, pos, PyString_FromString(s));
 533}
 534
 535static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel)
 536{
 537        struct tables *tables = container_of(dbe, struct tables, dbe);
 538        PyObject *t;
 539
 540        t = tuple_new(2);
 541
 542        tuple_set_u64(t, 0, evsel->db_id);
 543        tuple_set_string(t, 1, perf_evsel__name(evsel));
 544
 545        call_object(tables->evsel_handler, t, "evsel_table");
 546
 547        Py_DECREF(t);
 548
 549        return 0;
 550}
 551
 552static int python_export_machine(struct db_export *dbe,
 553                                 struct machine *machine)
 554{
 555        struct tables *tables = container_of(dbe, struct tables, dbe);
 556        PyObject *t;
 557
 558        t = tuple_new(3);
 559
 560        tuple_set_u64(t, 0, machine->db_id);
 561        tuple_set_s32(t, 1, machine->pid);
 562        tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : "");
 563
 564        call_object(tables->machine_handler, t, "machine_table");
 565
 566        Py_DECREF(t);
 567
 568        return 0;
 569}
 570
 571static int python_export_thread(struct db_export *dbe, struct thread *thread,
 572                                u64 main_thread_db_id, struct machine *machine)
 573{
 574        struct tables *tables = container_of(dbe, struct tables, dbe);
 575        PyObject *t;
 576
 577        t = tuple_new(5);
 578
 579        tuple_set_u64(t, 0, thread->db_id);
 580        tuple_set_u64(t, 1, machine->db_id);
 581        tuple_set_u64(t, 2, main_thread_db_id);
 582        tuple_set_s32(t, 3, thread->pid_);
 583        tuple_set_s32(t, 4, thread->tid);
 584
 585        call_object(tables->thread_handler, t, "thread_table");
 586
 587        Py_DECREF(t);
 588
 589        return 0;
 590}
 591
 592static int python_export_comm(struct db_export *dbe, struct comm *comm)
 593{
 594        struct tables *tables = container_of(dbe, struct tables, dbe);
 595        PyObject *t;
 596
 597        t = tuple_new(2);
 598
 599        tuple_set_u64(t, 0, comm->db_id);
 600        tuple_set_string(t, 1, comm__str(comm));
 601
 602        call_object(tables->comm_handler, t, "comm_table");
 603
 604        Py_DECREF(t);
 605
 606        return 0;
 607}
 608
 609static int python_export_comm_thread(struct db_export *dbe, u64 db_id,
 610                                     struct comm *comm, struct thread *thread)
 611{
 612        struct tables *tables = container_of(dbe, struct tables, dbe);
 613        PyObject *t;
 614
 615        t = tuple_new(3);
 616
 617        tuple_set_u64(t, 0, db_id);
 618        tuple_set_u64(t, 1, comm->db_id);
 619        tuple_set_u64(t, 2, thread->db_id);
 620
 621        call_object(tables->comm_thread_handler, t, "comm_thread_table");
 622
 623        Py_DECREF(t);
 624
 625        return 0;
 626}
 627
 628static int python_export_dso(struct db_export *dbe, struct dso *dso,
 629                             struct machine *machine)
 630{
 631        struct tables *tables = container_of(dbe, struct tables, dbe);
 632        char sbuild_id[SBUILD_ID_SIZE];
 633        PyObject *t;
 634
 635        build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
 636
 637        t = tuple_new(5);
 638
 639        tuple_set_u64(t, 0, dso->db_id);
 640        tuple_set_u64(t, 1, machine->db_id);
 641        tuple_set_string(t, 2, dso->short_name);
 642        tuple_set_string(t, 3, dso->long_name);
 643        tuple_set_string(t, 4, sbuild_id);
 644
 645        call_object(tables->dso_handler, t, "dso_table");
 646
 647        Py_DECREF(t);
 648
 649        return 0;
 650}
 651
 652static int python_export_symbol(struct db_export *dbe, struct symbol *sym,
 653                                struct dso *dso)
 654{
 655        struct tables *tables = container_of(dbe, struct tables, dbe);
 656        u64 *sym_db_id = symbol__priv(sym);
 657        PyObject *t;
 658
 659        t = tuple_new(6);
 660
 661        tuple_set_u64(t, 0, *sym_db_id);
 662        tuple_set_u64(t, 1, dso->db_id);
 663        tuple_set_u64(t, 2, sym->start);
 664        tuple_set_u64(t, 3, sym->end);
 665        tuple_set_s32(t, 4, sym->binding);
 666        tuple_set_string(t, 5, sym->name);
 667
 668        call_object(tables->symbol_handler, t, "symbol_table");
 669
 670        Py_DECREF(t);
 671
 672        return 0;
 673}
 674
 675static int python_export_branch_type(struct db_export *dbe, u32 branch_type,
 676                                     const char *name)
 677{
 678        struct tables *tables = container_of(dbe, struct tables, dbe);
 679        PyObject *t;
 680
 681        t = tuple_new(2);
 682
 683        tuple_set_s32(t, 0, branch_type);
 684        tuple_set_string(t, 1, name);
 685
 686        call_object(tables->branch_type_handler, t, "branch_type_table");
 687
 688        Py_DECREF(t);
 689
 690        return 0;
 691}
 692
 693static int python_export_sample(struct db_export *dbe,
 694                                struct export_sample *es)
 695{
 696        struct tables *tables = container_of(dbe, struct tables, dbe);
 697        PyObject *t;
 698
 699        t = tuple_new(22);
 700
 701        tuple_set_u64(t, 0, es->db_id);
 702        tuple_set_u64(t, 1, es->evsel->db_id);
 703        tuple_set_u64(t, 2, es->al->machine->db_id);
 704        tuple_set_u64(t, 3, es->al->thread->db_id);
 705        tuple_set_u64(t, 4, es->comm_db_id);
 706        tuple_set_u64(t, 5, es->dso_db_id);
 707        tuple_set_u64(t, 6, es->sym_db_id);
 708        tuple_set_u64(t, 7, es->offset);
 709        tuple_set_u64(t, 8, es->sample->ip);
 710        tuple_set_u64(t, 9, es->sample->time);
 711        tuple_set_s32(t, 10, es->sample->cpu);
 712        tuple_set_u64(t, 11, es->addr_dso_db_id);
 713        tuple_set_u64(t, 12, es->addr_sym_db_id);
 714        tuple_set_u64(t, 13, es->addr_offset);
 715        tuple_set_u64(t, 14, es->sample->addr);
 716        tuple_set_u64(t, 15, es->sample->period);
 717        tuple_set_u64(t, 16, es->sample->weight);
 718        tuple_set_u64(t, 17, es->sample->transaction);
 719        tuple_set_u64(t, 18, es->sample->data_src);
 720        tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK);
 721        tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX));
 722        tuple_set_u64(t, 21, es->call_path_id);
 723
 724        call_object(tables->sample_handler, t, "sample_table");
 725
 726        Py_DECREF(t);
 727
 728        return 0;
 729}
 730
 731static int python_export_call_path(struct db_export *dbe, struct call_path *cp)
 732{
 733        struct tables *tables = container_of(dbe, struct tables, dbe);
 734        PyObject *t;
 735        u64 parent_db_id, sym_db_id;
 736
 737        parent_db_id = cp->parent ? cp->parent->db_id : 0;
 738        sym_db_id = cp->sym ? *(u64 *)symbol__priv(cp->sym) : 0;
 739
 740        t = tuple_new(4);
 741
 742        tuple_set_u64(t, 0, cp->db_id);
 743        tuple_set_u64(t, 1, parent_db_id);
 744        tuple_set_u64(t, 2, sym_db_id);
 745        tuple_set_u64(t, 3, cp->ip);
 746
 747        call_object(tables->call_path_handler, t, "call_path_table");
 748
 749        Py_DECREF(t);
 750
 751        return 0;
 752}
 753
 754static int python_export_call_return(struct db_export *dbe,
 755                                     struct call_return *cr)
 756{
 757        struct tables *tables = container_of(dbe, struct tables, dbe);
 758        u64 comm_db_id = cr->comm ? cr->comm->db_id : 0;
 759        PyObject *t;
 760
 761        t = tuple_new(11);
 762
 763        tuple_set_u64(t, 0, cr->db_id);
 764        tuple_set_u64(t, 1, cr->thread->db_id);
 765        tuple_set_u64(t, 2, comm_db_id);
 766        tuple_set_u64(t, 3, cr->cp->db_id);
 767        tuple_set_u64(t, 4, cr->call_time);
 768        tuple_set_u64(t, 5, cr->return_time);
 769        tuple_set_u64(t, 6, cr->branch_count);
 770        tuple_set_u64(t, 7, cr->call_ref);
 771        tuple_set_u64(t, 8, cr->return_ref);
 772        tuple_set_u64(t, 9, cr->cp->parent->db_id);
 773        tuple_set_s32(t, 10, cr->flags);
 774
 775        call_object(tables->call_return_handler, t, "call_return_table");
 776
 777        Py_DECREF(t);
 778
 779        return 0;
 780}
 781
 782static int python_process_call_return(struct call_return *cr, void *data)
 783{
 784        struct db_export *dbe = data;
 785
 786        return db_export__call_return(dbe, cr);
 787}
 788
 789static void python_process_general_event(struct perf_sample *sample,
 790                                         struct perf_evsel *evsel,
 791                                         struct addr_location *al)
 792{
 793        PyObject *handler, *t, *dict, *callchain, *dict_sample;
 794        static char handler_name[64];
 795        unsigned n = 0;
 796
 797        /*
 798         * Use the MAX_FIELDS to make the function expandable, though
 799         * currently there is only one item for the tuple.
 800         */
 801        t = PyTuple_New(MAX_FIELDS);
 802        if (!t)
 803                Py_FatalError("couldn't create Python tuple");
 804
 805        dict = PyDict_New();
 806        if (!dict)
 807                Py_FatalError("couldn't create Python dictionary");
 808
 809        dict_sample = PyDict_New();
 810        if (!dict_sample)
 811                Py_FatalError("couldn't create Python dictionary");
 812
 813        snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
 814
 815        handler = get_handler(handler_name);
 816        if (!handler)
 817                goto exit;
 818
 819        pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
 820        pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
 821                        (const char *)&evsel->attr, sizeof(evsel->attr)));
 822
 823        pydict_set_item_string_decref(dict_sample, "pid",
 824                        PyInt_FromLong(sample->pid));
 825        pydict_set_item_string_decref(dict_sample, "tid",
 826                        PyInt_FromLong(sample->tid));
 827        pydict_set_item_string_decref(dict_sample, "cpu",
 828                        PyInt_FromLong(sample->cpu));
 829        pydict_set_item_string_decref(dict_sample, "ip",
 830                        PyLong_FromUnsignedLongLong(sample->ip));
 831        pydict_set_item_string_decref(dict_sample, "time",
 832                        PyLong_FromUnsignedLongLong(sample->time));
 833        pydict_set_item_string_decref(dict_sample, "period",
 834                        PyLong_FromUnsignedLongLong(sample->period));
 835        pydict_set_item_string_decref(dict, "sample", dict_sample);
 836
 837        pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
 838                        (const char *)sample->raw_data, sample->raw_size));
 839        pydict_set_item_string_decref(dict, "comm",
 840                        PyString_FromString(thread__comm_str(al->thread)));
 841        if (al->map) {
 842                pydict_set_item_string_decref(dict, "dso",
 843                        PyString_FromString(al->map->dso->name));
 844        }
 845        if (al->sym) {
 846                pydict_set_item_string_decref(dict, "symbol",
 847                        PyString_FromString(al->sym->name));
 848        }
 849
 850        /* ip unwinding */
 851        callchain = python_process_callchain(sample, evsel, al);
 852        pydict_set_item_string_decref(dict, "callchain", callchain);
 853
 854        PyTuple_SetItem(t, n++, dict);
 855        if (_PyTuple_Resize(&t, n) == -1)
 856                Py_FatalError("error resizing Python tuple");
 857
 858        call_object(handler, t, handler_name);
 859exit:
 860        Py_DECREF(dict);
 861        Py_DECREF(t);
 862}
 863
 864static void python_process_event(union perf_event *event,
 865                                 struct perf_sample *sample,
 866                                 struct perf_evsel *evsel,
 867                                 struct addr_location *al)
 868{
 869        struct tables *tables = &tables_global;
 870
 871        switch (evsel->attr.type) {
 872        case PERF_TYPE_TRACEPOINT:
 873                python_process_tracepoint(sample, evsel, al);
 874                break;
 875        /* Reserve for future process_hw/sw/raw APIs */
 876        default:
 877                if (tables->db_export_mode)
 878                        db_export__sample(&tables->dbe, event, sample, evsel, al);
 879                else
 880                        python_process_general_event(sample, evsel, al);
 881        }
 882}
 883
 884static void get_handler_name(char *str, size_t size,
 885                             struct perf_evsel *evsel)
 886{
 887        char *p = str;
 888
 889        scnprintf(str, size, "stat__%s", perf_evsel__name(evsel));
 890
 891        while ((p = strchr(p, ':'))) {
 892                *p = '_';
 893                p++;
 894        }
 895}
 896
 897static void
 898process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp,
 899             struct perf_counts_values *count)
 900{
 901        PyObject *handler, *t;
 902        static char handler_name[256];
 903        int n = 0;
 904
 905        t = PyTuple_New(MAX_FIELDS);
 906        if (!t)
 907                Py_FatalError("couldn't create Python tuple");
 908
 909        get_handler_name(handler_name, sizeof(handler_name),
 910                         counter);
 911
 912        handler = get_handler(handler_name);
 913        if (!handler) {
 914                pr_debug("can't find python handler %s\n", handler_name);
 915                return;
 916        }
 917
 918        PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
 919        PyTuple_SetItem(t, n++, PyInt_FromLong(thread));
 920
 921        tuple_set_u64(t, n++, tstamp);
 922        tuple_set_u64(t, n++, count->val);
 923        tuple_set_u64(t, n++, count->ena);
 924        tuple_set_u64(t, n++, count->run);
 925
 926        if (_PyTuple_Resize(&t, n) == -1)
 927                Py_FatalError("error resizing Python tuple");
 928
 929        call_object(handler, t, handler_name);
 930
 931        Py_DECREF(t);
 932}
 933
 934static void python_process_stat(struct perf_stat_config *config,
 935                                struct perf_evsel *counter, u64 tstamp)
 936{
 937        struct thread_map *threads = counter->threads;
 938        struct cpu_map *cpus = counter->cpus;
 939        int cpu, thread;
 940
 941        if (config->aggr_mode == AGGR_GLOBAL) {
 942                process_stat(counter, -1, -1, tstamp,
 943                             &counter->counts->aggr);
 944                return;
 945        }
 946
 947        for (thread = 0; thread < threads->nr; thread++) {
 948                for (cpu = 0; cpu < cpus->nr; cpu++) {
 949                        process_stat(counter, cpus->map[cpu],
 950                                     thread_map__pid(threads, thread), tstamp,
 951                                     perf_counts(counter->counts, cpu, thread));
 952                }
 953        }
 954}
 955
 956static void python_process_stat_interval(u64 tstamp)
 957{
 958        PyObject *handler, *t;
 959        static const char handler_name[] = "stat__interval";
 960        int n = 0;
 961
 962        t = PyTuple_New(MAX_FIELDS);
 963        if (!t)
 964                Py_FatalError("couldn't create Python tuple");
 965
 966        handler = get_handler(handler_name);
 967        if (!handler) {
 968                pr_debug("can't find python handler %s\n", handler_name);
 969                return;
 970        }
 971
 972        tuple_set_u64(t, n++, tstamp);
 973
 974        if (_PyTuple_Resize(&t, n) == -1)
 975                Py_FatalError("error resizing Python tuple");
 976
 977        call_object(handler, t, handler_name);
 978
 979        Py_DECREF(t);
 980}
 981
 982static int run_start_sub(void)
 983{
 984        main_module = PyImport_AddModule("__main__");
 985        if (main_module == NULL)
 986                return -1;
 987        Py_INCREF(main_module);
 988
 989        main_dict = PyModule_GetDict(main_module);
 990        if (main_dict == NULL)
 991                goto error;
 992        Py_INCREF(main_dict);
 993
 994        try_call_object("trace_begin", NULL);
 995
 996        return 0;
 997
 998error:
 999        Py_XDECREF(main_dict);
1000        Py_XDECREF(main_module);
1001        return -1;
1002}
1003
1004#define SET_TABLE_HANDLER_(name, handler_name, table_name) do {         \
1005        tables->handler_name = get_handler(#table_name);                \
1006        if (tables->handler_name)                                       \
1007                tables->dbe.export_ ## name = python_export_ ## name;   \
1008} while (0)
1009
1010#define SET_TABLE_HANDLER(name) \
1011        SET_TABLE_HANDLER_(name, name ## _handler, name ## _table)
1012
1013static void set_table_handlers(struct tables *tables)
1014{
1015        const char *perf_db_export_mode = "perf_db_export_mode";
1016        const char *perf_db_export_calls = "perf_db_export_calls";
1017        const char *perf_db_export_callchains = "perf_db_export_callchains";
1018        PyObject *db_export_mode, *db_export_calls, *db_export_callchains;
1019        bool export_calls = false;
1020        bool export_callchains = false;
1021        int ret;
1022
1023        memset(tables, 0, sizeof(struct tables));
1024        if (db_export__init(&tables->dbe))
1025                Py_FatalError("failed to initialize export");
1026
1027        db_export_mode = PyDict_GetItemString(main_dict, perf_db_export_mode);
1028        if (!db_export_mode)
1029                return;
1030
1031        ret = PyObject_IsTrue(db_export_mode);
1032        if (ret == -1)
1033                handler_call_die(perf_db_export_mode);
1034        if (!ret)
1035                return;
1036
1037        /* handle export calls */
1038        tables->dbe.crp = NULL;
1039        db_export_calls = PyDict_GetItemString(main_dict, perf_db_export_calls);
1040        if (db_export_calls) {
1041                ret = PyObject_IsTrue(db_export_calls);
1042                if (ret == -1)
1043                        handler_call_die(perf_db_export_calls);
1044                export_calls = !!ret;
1045        }
1046
1047        if (export_calls) {
1048                tables->dbe.crp =
1049                        call_return_processor__new(python_process_call_return,
1050                                                   &tables->dbe);
1051                if (!tables->dbe.crp)
1052                        Py_FatalError("failed to create calls processor");
1053        }
1054
1055        /* handle export callchains */
1056        tables->dbe.cpr = NULL;
1057        db_export_callchains = PyDict_GetItemString(main_dict,
1058                                                    perf_db_export_callchains);
1059        if (db_export_callchains) {
1060                ret = PyObject_IsTrue(db_export_callchains);
1061                if (ret == -1)
1062                        handler_call_die(perf_db_export_callchains);
1063                export_callchains = !!ret;
1064        }
1065
1066        if (export_callchains) {
1067                /*
1068                 * Attempt to use the call path root from the call return
1069                 * processor, if the call return processor is in use. Otherwise,
1070                 * we allocate a new call path root. This prevents exporting
1071                 * duplicate call path ids when both are in use simultaniously.
1072                 */
1073                if (tables->dbe.crp)
1074                        tables->dbe.cpr = tables->dbe.crp->cpr;
1075                else
1076                        tables->dbe.cpr = call_path_root__new();
1077
1078                if (!tables->dbe.cpr)
1079                        Py_FatalError("failed to create call path root");
1080        }
1081
1082        tables->db_export_mode = true;
1083        /*
1084         * Reserve per symbol space for symbol->db_id via symbol__priv()
1085         */
1086        symbol_conf.priv_size = sizeof(u64);
1087
1088        SET_TABLE_HANDLER(evsel);
1089        SET_TABLE_HANDLER(machine);
1090        SET_TABLE_HANDLER(thread);
1091        SET_TABLE_HANDLER(comm);
1092        SET_TABLE_HANDLER(comm_thread);
1093        SET_TABLE_HANDLER(dso);
1094        SET_TABLE_HANDLER(symbol);
1095        SET_TABLE_HANDLER(branch_type);
1096        SET_TABLE_HANDLER(sample);
1097        SET_TABLE_HANDLER(call_path);
1098        SET_TABLE_HANDLER(call_return);
1099}
1100
1101/*
1102 * Start trace script
1103 */
1104static int python_start_script(const char *script, int argc, const char **argv)
1105{
1106        struct tables *tables = &tables_global;
1107        const char **command_line;
1108        char buf[PATH_MAX];
1109        int i, err = 0;
1110        FILE *fp;
1111
1112        command_line = malloc((argc + 1) * sizeof(const char *));
1113        command_line[0] = script;
1114        for (i = 1; i < argc + 1; i++)
1115                command_line[i] = argv[i - 1];
1116
1117        Py_Initialize();
1118
1119        initperf_trace_context();
1120
1121        PySys_SetArgv(argc + 1, (char **)command_line);
1122
1123        fp = fopen(script, "r");
1124        if (!fp) {
1125                sprintf(buf, "Can't open python script \"%s\"", script);
1126                perror(buf);
1127                err = -1;
1128                goto error;
1129        }
1130
1131        err = PyRun_SimpleFile(fp, script);
1132        if (err) {
1133                fprintf(stderr, "Error running python script %s\n", script);
1134                goto error;
1135        }
1136
1137        err = run_start_sub();
1138        if (err) {
1139                fprintf(stderr, "Error starting python script %s\n", script);
1140                goto error;
1141        }
1142
1143        set_table_handlers(tables);
1144
1145        if (tables->db_export_mode) {
1146                err = db_export__branch_types(&tables->dbe);
1147                if (err)
1148                        goto error;
1149        }
1150
1151        free(command_line);
1152
1153        return err;
1154error:
1155        Py_Finalize();
1156        free(command_line);
1157
1158        return err;
1159}
1160
1161static int python_flush_script(void)
1162{
1163        struct tables *tables = &tables_global;
1164
1165        return db_export__flush(&tables->dbe);
1166}
1167
1168/*
1169 * Stop trace script
1170 */
1171static int python_stop_script(void)
1172{
1173        struct tables *tables = &tables_global;
1174
1175        try_call_object("trace_end", NULL);
1176
1177        db_export__exit(&tables->dbe);
1178
1179        Py_XDECREF(main_dict);
1180        Py_XDECREF(main_module);
1181        Py_Finalize();
1182
1183        return 0;
1184}
1185
1186static int python_generate_script(struct pevent *pevent, const char *outfile)
1187{
1188        struct event_format *event = NULL;
1189        struct format_field *f;
1190        char fname[PATH_MAX];
1191        int not_first, count;
1192        FILE *ofp;
1193
1194        sprintf(fname, "%s.py", outfile);
1195        ofp = fopen(fname, "w");
1196        if (ofp == NULL) {
1197                fprintf(stderr, "couldn't open %s\n", fname);
1198                return -1;
1199        }
1200        fprintf(ofp, "# perf script event handlers, "
1201                "generated by perf script -g python\n");
1202
1203        fprintf(ofp, "# Licensed under the terms of the GNU GPL"
1204                " License version 2\n\n");
1205
1206        fprintf(ofp, "# The common_* event handler fields are the most useful "
1207                "fields common to\n");
1208
1209        fprintf(ofp, "# all events.  They don't necessarily correspond to "
1210                "the 'common_*' fields\n");
1211
1212        fprintf(ofp, "# in the format files.  Those fields not available as "
1213                "handler params can\n");
1214
1215        fprintf(ofp, "# be retrieved using Python functions of the form "
1216                "common_*(context).\n");
1217
1218        fprintf(ofp, "# See the perf-trace-python Documentation for the list "
1219                "of available functions.\n\n");
1220
1221        fprintf(ofp, "import os\n");
1222        fprintf(ofp, "import sys\n\n");
1223
1224        fprintf(ofp, "sys.path.append(os.environ['PERF_EXEC_PATH'] + \\\n");
1225        fprintf(ofp, "\t'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')\n");
1226        fprintf(ofp, "\nfrom perf_trace_context import *\n");
1227        fprintf(ofp, "from Core import *\n\n\n");
1228
1229        fprintf(ofp, "def trace_begin():\n");
1230        fprintf(ofp, "\tprint \"in trace_begin\"\n\n");
1231
1232        fprintf(ofp, "def trace_end():\n");
1233        fprintf(ofp, "\tprint \"in trace_end\"\n\n");
1234
1235        while ((event = trace_find_next_event(pevent, event))) {
1236                fprintf(ofp, "def %s__%s(", event->system, event->name);
1237                fprintf(ofp, "event_name, ");
1238                fprintf(ofp, "context, ");
1239                fprintf(ofp, "common_cpu,\n");
1240                fprintf(ofp, "\tcommon_secs, ");
1241                fprintf(ofp, "common_nsecs, ");
1242                fprintf(ofp, "common_pid, ");
1243                fprintf(ofp, "common_comm,\n\t");
1244                fprintf(ofp, "common_callchain, ");
1245
1246                not_first = 0;
1247                count = 0;
1248
1249                for (f = event->format.fields; f; f = f->next) {
1250                        if (not_first++)
1251                                fprintf(ofp, ", ");
1252                        if (++count % 5 == 0)
1253                                fprintf(ofp, "\n\t");
1254
1255                        fprintf(ofp, "%s", f->name);
1256                }
1257                fprintf(ofp, "):\n");
1258
1259                fprintf(ofp, "\t\tprint_header(event_name, common_cpu, "
1260                        "common_secs, common_nsecs,\n\t\t\t"
1261                        "common_pid, common_comm)\n\n");
1262
1263                fprintf(ofp, "\t\tprint \"");
1264
1265                not_first = 0;
1266                count = 0;
1267
1268                for (f = event->format.fields; f; f = f->next) {
1269                        if (not_first++)
1270                                fprintf(ofp, ", ");
1271                        if (count && count % 3 == 0) {
1272                                fprintf(ofp, "\" \\\n\t\t\"");
1273                        }
1274                        count++;
1275
1276                        fprintf(ofp, "%s=", f->name);
1277                        if (f->flags & FIELD_IS_STRING ||
1278                            f->flags & FIELD_IS_FLAG ||
1279                            f->flags & FIELD_IS_ARRAY ||
1280                            f->flags & FIELD_IS_SYMBOLIC)
1281                                fprintf(ofp, "%%s");
1282                        else if (f->flags & FIELD_IS_SIGNED)
1283                                fprintf(ofp, "%%d");
1284                        else
1285                                fprintf(ofp, "%%u");
1286                }
1287
1288                fprintf(ofp, "\" %% \\\n\t\t(");
1289
1290                not_first = 0;
1291                count = 0;
1292
1293                for (f = event->format.fields; f; f = f->next) {
1294                        if (not_first++)
1295                                fprintf(ofp, ", ");
1296
1297                        if (++count % 5 == 0)
1298                                fprintf(ofp, "\n\t\t");
1299
1300                        if (f->flags & FIELD_IS_FLAG) {
1301                                if ((count - 1) % 5 != 0) {
1302                                        fprintf(ofp, "\n\t\t");
1303                                        count = 4;
1304                                }
1305                                fprintf(ofp, "flag_str(\"");
1306                                fprintf(ofp, "%s__%s\", ", event->system,
1307                                        event->name);
1308                                fprintf(ofp, "\"%s\", %s)", f->name,
1309                                        f->name);
1310                        } else if (f->flags & FIELD_IS_SYMBOLIC) {
1311                                if ((count - 1) % 5 != 0) {
1312                                        fprintf(ofp, "\n\t\t");
1313                                        count = 4;
1314                                }
1315                                fprintf(ofp, "symbol_str(\"");
1316                                fprintf(ofp, "%s__%s\", ", event->system,
1317                                        event->name);
1318                                fprintf(ofp, "\"%s\", %s)", f->name,
1319                                        f->name);
1320                        } else
1321                                fprintf(ofp, "%s", f->name);
1322                }
1323
1324                fprintf(ofp, ")\n\n");
1325
1326                fprintf(ofp, "\t\tfor node in common_callchain:");
1327                fprintf(ofp, "\n\t\t\tif 'sym' in node:");
1328                fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])");
1329                fprintf(ofp, "\n\t\t\telse:");
1330                fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n");
1331                fprintf(ofp, "\t\tprint \"\\n\"\n\n");
1332
1333        }
1334
1335        fprintf(ofp, "def trace_unhandled(event_name, context, "
1336                "event_fields_dict):\n");
1337
1338        fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))"
1339                "for k,v in sorted(event_fields_dict.items())])\n\n");
1340
1341        fprintf(ofp, "def print_header("
1342                "event_name, cpu, secs, nsecs, pid, comm):\n"
1343                "\tprint \"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t"
1344                "(event_name, cpu, secs, nsecs, pid, comm),\n");
1345
1346        fclose(ofp);
1347
1348        fprintf(stderr, "generated Python script: %s\n", fname);
1349
1350        return 0;
1351}
1352
1353struct scripting_ops python_scripting_ops = {
1354        .name                   = "Python",
1355        .start_script           = python_start_script,
1356        .flush_script           = python_flush_script,
1357        .stop_script            = python_stop_script,
1358        .process_event          = python_process_event,
1359        .process_stat           = python_process_stat,
1360        .process_stat_interval  = python_process_stat_interval,
1361        .generate_script        = python_generate_script,
1362};
1363