diff options
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 408 |
1 files changed, 318 insertions, 90 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 4e4aa4c97ac5..c0c010350bc2 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -687,7 +687,7 @@ static void set_sample_datasrc_in_dict(PyObject *dict, _PyUnicode_FromString(decode)); } -static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) +static void regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) { unsigned int i = 0, r; int printed = 0; @@ -695,7 +695,7 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) bf[0] = 0; if (!regs || !regs->regs) - return 0; + return; for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { u64 val = regs->regs[i++]; @@ -704,8 +704,6 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) "%5s:0x%" PRIx64 " ", perf_reg_name(r), val); } - - return printed; } static void set_regs_in_dict(PyObject *dict, @@ -713,7 +711,16 @@ static void set_regs_in_dict(PyObject *dict, struct evsel *evsel) { struct perf_event_attr *attr = &evsel->core.attr; - char bf[512]; + + /* + * Here value 28 is a constant size which can be used to print + * one register value and its corresponds to: + * 16 chars is to specify 64 bit register in hexadecimal. + * 2 chars is for appending "0x" to the hexadecimal value and + * 10 chars is for register name. + */ + int size = __sw_hweight64(attr->sample_regs_intr) * 28; + char bf[size]; regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); @@ -726,9 +733,49 @@ static void set_regs_in_dict(PyObject *dict, _PyUnicode_FromString(bf)); } +static void set_sym_in_dict(PyObject *dict, struct addr_location *al, + const char *dso_field, const char *sym_field, + const char *symoff_field) +{ + if (al->map) { + pydict_set_item_string_decref(dict, dso_field, + _PyUnicode_FromString(al->map->dso->name)); + } + if (al->sym) { + pydict_set_item_string_decref(dict, sym_field, + _PyUnicode_FromString(al->sym->name)); + pydict_set_item_string_decref(dict, symoff_field, + PyLong_FromUnsignedLong(get_offset(al->sym, al))); + } +} + +static void set_sample_flags(PyObject *dict, u32 flags) +{ + const char *ch = PERF_IP_FLAG_CHARS; + char *p, str[33]; + + for (p = str; *ch; ch++, flags >>= 1) { + if (flags & 1) + *p++ = *ch; + } + *p = 0; + pydict_set_item_string_decref(dict, "flags", _PyUnicode_FromString(str)); +} + +static void python_process_sample_flags(struct perf_sample *sample, PyObject *dict_sample) +{ + char flags_disp[SAMPLE_FLAGS_BUF_SIZE]; + + set_sample_flags(dict_sample, sample->flags); + perf_sample__sprintf_flags(sample->flags, flags_disp, sizeof(flags_disp)); + pydict_set_item_string_decref(dict_sample, "flags_disp", + _PyUnicode_FromString(flags_disp)); +} + static PyObject *get_perf_sample_dict(struct perf_sample *sample, struct evsel *evsel, struct addr_location *al, + struct addr_location *addr_al, PyObject *callchain) { PyObject *dict, *dict_sample, *brstack, *brstacksym; @@ -772,14 +819,7 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, (const char *)sample->raw_data, sample->raw_size)); pydict_set_item_string_decref(dict, "comm", _PyUnicode_FromString(thread__comm_str(al->thread))); - if (al->map) { - pydict_set_item_string_decref(dict, "dso", - _PyUnicode_FromString(al->map->dso->name)); - } - if (al->sym) { - pydict_set_item_string_decref(dict, "symbol", - _PyUnicode_FromString(al->sym->name)); - } + set_sym_in_dict(dict, al, "dso", "symbol", "symoff"); pydict_set_item_string_decref(dict, "callchain", callchain); @@ -789,6 +829,26 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, brstacksym = python_process_brstacksym(sample, al->thread); pydict_set_item_string_decref(dict, "brstacksym", brstacksym); + pydict_set_item_string_decref(dict_sample, "cpumode", + _PyLong_FromLong((unsigned long)sample->cpumode)); + + if (addr_al) { + pydict_set_item_string_decref(dict_sample, "addr_correlates_sym", + PyBool_FromLong(1)); + set_sym_in_dict(dict_sample, addr_al, "addr_dso", "addr_symbol", "addr_symoff"); + } + + if (sample->flags) + python_process_sample_flags(sample, dict_sample); + + /* Instructions per cycle (IPC) */ + if (sample->insn_cnt && sample->cyc_cnt) { + pydict_set_item_string_decref(dict_sample, "insn_cnt", + PyLong_FromUnsignedLongLong(sample->insn_cnt)); + pydict_set_item_string_decref(dict_sample, "cyc_cnt", + PyLong_FromUnsignedLongLong(sample->cyc_cnt)); + } + set_regs_in_dict(dict, sample, evsel); return dict; @@ -796,7 +856,8 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, static void python_process_tracepoint(struct perf_sample *sample, struct evsel *evsel, - struct addr_location *al) + struct addr_location *al, + struct addr_location *addr_al) { struct tep_event *event = evsel->tp_format; PyObject *handler, *context, *t, *obj = NULL, *callchain; @@ -843,9 +904,6 @@ static void python_process_tracepoint(struct perf_sample *sample, s = nsecs / NSEC_PER_SEC; ns = nsecs - s * NSEC_PER_SEC; - scripting_context->event_data = data; - scripting_context->pevent = evsel->tp_format->tep; - context = _PyCapsule_New(scripting_context, NULL, NULL); PyTuple_SetItem(t, n++, _PyUnicode_FromString(handler_name)); @@ -906,7 +964,7 @@ static void python_process_tracepoint(struct perf_sample *sample, PyTuple_SetItem(t, n++, dict); if (get_argument_count(handler) == (int) n + 1) { - all_entries_dict = get_perf_sample_dict(sample, evsel, al, + all_entries_dict = get_perf_sample_dict(sample, evsel, al, addr_al, callchain); PyTuple_SetItem(t, n++, all_entries_dict); } else { @@ -934,7 +992,7 @@ static PyObject *tuple_new(unsigned int sz) return t; } -static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) +static int tuple_set_s64(PyObject *t, unsigned int pos, s64 val) { #if BITS_PER_LONG == 64 return PyTuple_SetItem(t, pos, _PyLong_FromLong(val)); @@ -944,11 +1002,37 @@ static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) #endif } +/* + * Databases support only signed 64-bit numbers, so even though we are + * exporting a u64, it must be as s64. + */ +#define tuple_set_d64 tuple_set_s64 + +static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) +{ +#if BITS_PER_LONG == 64 + return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLong(val)); +#endif +#if BITS_PER_LONG == 32 + return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLongLong(val)); +#endif +} + +static int tuple_set_u32(PyObject *t, unsigned int pos, u32 val) +{ + return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLong(val)); +} + static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val) { return PyTuple_SetItem(t, pos, _PyLong_FromLong(val)); } +static int tuple_set_bool(PyObject *t, unsigned int pos, bool val) +{ + return PyTuple_SetItem(t, pos, PyBool_FromLong(val)); +} + static int tuple_set_string(PyObject *t, unsigned int pos, const char *s) { return PyTuple_SetItem(t, pos, _PyUnicode_FromString(s)); @@ -967,7 +1051,7 @@ static int python_export_evsel(struct db_export *dbe, struct evsel *evsel) t = tuple_new(2); - tuple_set_u64(t, 0, evsel->db_id); + tuple_set_d64(t, 0, evsel->db_id); tuple_set_string(t, 1, evsel__name(evsel)); call_object(tables->evsel_handler, t, "evsel_table"); @@ -985,7 +1069,7 @@ static int python_export_machine(struct db_export *dbe, t = tuple_new(3); - tuple_set_u64(t, 0, machine->db_id); + tuple_set_d64(t, 0, machine->db_id); tuple_set_s32(t, 1, machine->pid); tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : ""); @@ -1004,9 +1088,9 @@ static int python_export_thread(struct db_export *dbe, struct thread *thread, t = tuple_new(5); - tuple_set_u64(t, 0, thread->db_id); - tuple_set_u64(t, 1, machine->db_id); - tuple_set_u64(t, 2, main_thread_db_id); + tuple_set_d64(t, 0, thread->db_id); + tuple_set_d64(t, 1, machine->db_id); + tuple_set_d64(t, 2, main_thread_db_id); tuple_set_s32(t, 3, thread->pid_); tuple_set_s32(t, 4, thread->tid); @@ -1025,10 +1109,10 @@ static int python_export_comm(struct db_export *dbe, struct comm *comm, t = tuple_new(5); - tuple_set_u64(t, 0, comm->db_id); + tuple_set_d64(t, 0, comm->db_id); tuple_set_string(t, 1, comm__str(comm)); - tuple_set_u64(t, 2, thread->db_id); - tuple_set_u64(t, 3, comm->start); + tuple_set_d64(t, 2, thread->db_id); + tuple_set_d64(t, 3, comm->start); tuple_set_s32(t, 4, comm->exec); call_object(tables->comm_handler, t, "comm_table"); @@ -1046,9 +1130,9 @@ static int python_export_comm_thread(struct db_export *dbe, u64 db_id, t = tuple_new(3); - tuple_set_u64(t, 0, db_id); - tuple_set_u64(t, 1, comm->db_id); - tuple_set_u64(t, 2, thread->db_id); + tuple_set_d64(t, 0, db_id); + tuple_set_d64(t, 1, comm->db_id); + tuple_set_d64(t, 2, thread->db_id); call_object(tables->comm_thread_handler, t, "comm_thread_table"); @@ -1068,8 +1152,8 @@ static int python_export_dso(struct db_export *dbe, struct dso *dso, t = tuple_new(5); - tuple_set_u64(t, 0, dso->db_id); - tuple_set_u64(t, 1, machine->db_id); + tuple_set_d64(t, 0, dso->db_id); + tuple_set_d64(t, 1, machine->db_id); tuple_set_string(t, 2, dso->short_name); tuple_set_string(t, 3, dso->long_name); tuple_set_string(t, 4, sbuild_id); @@ -1090,10 +1174,10 @@ static int python_export_symbol(struct db_export *dbe, struct symbol *sym, t = tuple_new(6); - tuple_set_u64(t, 0, *sym_db_id); - tuple_set_u64(t, 1, dso->db_id); - tuple_set_u64(t, 2, sym->start); - tuple_set_u64(t, 3, sym->end); + tuple_set_d64(t, 0, *sym_db_id); + tuple_set_d64(t, 1, dso->db_id); + tuple_set_d64(t, 2, sym->start); + tuple_set_d64(t, 3, sym->end); tuple_set_s32(t, 4, sym->binding); tuple_set_string(t, 5, sym->name); @@ -1130,30 +1214,30 @@ static void python_export_sample_table(struct db_export *dbe, t = tuple_new(24); - tuple_set_u64(t, 0, es->db_id); - tuple_set_u64(t, 1, es->evsel->db_id); - tuple_set_u64(t, 2, es->al->maps->machine->db_id); - tuple_set_u64(t, 3, es->al->thread->db_id); - tuple_set_u64(t, 4, es->comm_db_id); - tuple_set_u64(t, 5, es->dso_db_id); - tuple_set_u64(t, 6, es->sym_db_id); - tuple_set_u64(t, 7, es->offset); - tuple_set_u64(t, 8, es->sample->ip); - tuple_set_u64(t, 9, es->sample->time); + tuple_set_d64(t, 0, es->db_id); + tuple_set_d64(t, 1, es->evsel->db_id); + tuple_set_d64(t, 2, es->al->maps->machine->db_id); + tuple_set_d64(t, 3, es->al->thread->db_id); + tuple_set_d64(t, 4, es->comm_db_id); + tuple_set_d64(t, 5, es->dso_db_id); + tuple_set_d64(t, 6, es->sym_db_id); + tuple_set_d64(t, 7, es->offset); + tuple_set_d64(t, 8, es->sample->ip); + tuple_set_d64(t, 9, es->sample->time); tuple_set_s32(t, 10, es->sample->cpu); - tuple_set_u64(t, 11, es->addr_dso_db_id); - tuple_set_u64(t, 12, es->addr_sym_db_id); - tuple_set_u64(t, 13, es->addr_offset); - tuple_set_u64(t, 14, es->sample->addr); - tuple_set_u64(t, 15, es->sample->period); - tuple_set_u64(t, 16, es->sample->weight); - tuple_set_u64(t, 17, es->sample->transaction); - tuple_set_u64(t, 18, es->sample->data_src); + tuple_set_d64(t, 11, es->addr_dso_db_id); + tuple_set_d64(t, 12, es->addr_sym_db_id); + tuple_set_d64(t, 13, es->addr_offset); + tuple_set_d64(t, 14, es->sample->addr); + tuple_set_d64(t, 15, es->sample->period); + tuple_set_d64(t, 16, es->sample->weight); + tuple_set_d64(t, 17, es->sample->transaction); + tuple_set_d64(t, 18, es->sample->data_src); tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK); tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX)); - tuple_set_u64(t, 21, es->call_path_id); - tuple_set_u64(t, 22, es->sample->insn_cnt); - tuple_set_u64(t, 23, es->sample->cyc_cnt); + tuple_set_d64(t, 21, es->call_path_id); + tuple_set_d64(t, 22, es->sample->insn_cnt); + tuple_set_d64(t, 23, es->sample->cyc_cnt); call_object(tables->sample_handler, t, "sample_table"); @@ -1167,8 +1251,8 @@ static void python_export_synth(struct db_export *dbe, struct export_sample *es) t = tuple_new(3); - tuple_set_u64(t, 0, es->db_id); - tuple_set_u64(t, 1, es->evsel->core.attr.config); + tuple_set_d64(t, 0, es->db_id); + tuple_set_d64(t, 1, es->evsel->core.attr.config); tuple_set_bytes(t, 2, es->sample->raw_data, es->sample->raw_size); call_object(tables->synth_handler, t, "synth_data"); @@ -1200,10 +1284,10 @@ static int python_export_call_path(struct db_export *dbe, struct call_path *cp) t = tuple_new(4); - tuple_set_u64(t, 0, cp->db_id); - tuple_set_u64(t, 1, parent_db_id); - tuple_set_u64(t, 2, sym_db_id); - tuple_set_u64(t, 3, cp->ip); + tuple_set_d64(t, 0, cp->db_id); + tuple_set_d64(t, 1, parent_db_id); + tuple_set_d64(t, 2, sym_db_id); + tuple_set_d64(t, 3, cp->ip); call_object(tables->call_path_handler, t, "call_path_table"); @@ -1221,20 +1305,20 @@ static int python_export_call_return(struct db_export *dbe, t = tuple_new(14); - tuple_set_u64(t, 0, cr->db_id); - tuple_set_u64(t, 1, cr->thread->db_id); - tuple_set_u64(t, 2, comm_db_id); - tuple_set_u64(t, 3, cr->cp->db_id); - tuple_set_u64(t, 4, cr->call_time); - tuple_set_u64(t, 5, cr->return_time); - tuple_set_u64(t, 6, cr->branch_count); - tuple_set_u64(t, 7, cr->call_ref); - tuple_set_u64(t, 8, cr->return_ref); - tuple_set_u64(t, 9, cr->cp->parent->db_id); + tuple_set_d64(t, 0, cr->db_id); + tuple_set_d64(t, 1, cr->thread->db_id); + tuple_set_d64(t, 2, comm_db_id); + tuple_set_d64(t, 3, cr->cp->db_id); + tuple_set_d64(t, 4, cr->call_time); + tuple_set_d64(t, 5, cr->return_time); + tuple_set_d64(t, 6, cr->branch_count); + tuple_set_d64(t, 7, cr->call_ref); + tuple_set_d64(t, 8, cr->return_ref); + tuple_set_d64(t, 9, cr->cp->parent->db_id); tuple_set_s32(t, 10, cr->flags); - tuple_set_u64(t, 11, cr->parent_db_id); - tuple_set_u64(t, 12, cr->insn_count); - tuple_set_u64(t, 13, cr->cyc_count); + tuple_set_d64(t, 11, cr->parent_db_id); + tuple_set_d64(t, 12, cr->insn_count); + tuple_set_d64(t, 13, cr->cyc_count); call_object(tables->call_return_handler, t, "call_return_table"); @@ -1254,14 +1338,14 @@ static int python_export_context_switch(struct db_export *dbe, u64 db_id, t = tuple_new(9); - tuple_set_u64(t, 0, db_id); - tuple_set_u64(t, 1, machine->db_id); - tuple_set_u64(t, 2, sample->time); + tuple_set_d64(t, 0, db_id); + tuple_set_d64(t, 1, machine->db_id); + tuple_set_d64(t, 2, sample->time); tuple_set_s32(t, 3, sample->cpu); - tuple_set_u64(t, 4, th_out_id); - tuple_set_u64(t, 5, comm_out_id); - tuple_set_u64(t, 6, th_in_id); - tuple_set_u64(t, 7, comm_in_id); + tuple_set_d64(t, 4, th_out_id); + tuple_set_d64(t, 5, comm_out_id); + tuple_set_d64(t, 6, th_in_id); + tuple_set_d64(t, 7, comm_in_id); tuple_set_s32(t, 8, flags); call_object(tables->context_switch_handler, t, "context_switch"); @@ -1281,7 +1365,8 @@ static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, static void python_process_general_event(struct perf_sample *sample, struct evsel *evsel, - struct addr_location *al) + struct addr_location *al, + struct addr_location *addr_al) { PyObject *handler, *t, *dict, *callchain; static char handler_name[64]; @@ -1303,7 +1388,7 @@ static void python_process_general_event(struct perf_sample *sample, /* ip unwinding */ callchain = python_process_callchain(sample, evsel, al); - dict = get_perf_sample_dict(sample, evsel, al, callchain); + dict = get_perf_sample_dict(sample, evsel, al, addr_al, callchain); PyTuple_SetItem(t, n++, dict); if (_PyTuple_Resize(&t, n) == -1) @@ -1317,21 +1402,93 @@ static void python_process_general_event(struct perf_sample *sample, static void python_process_event(union perf_event *event, struct perf_sample *sample, struct evsel *evsel, - struct addr_location *al) + struct addr_location *al, + struct addr_location *addr_al) { struct tables *tables = &tables_global; + scripting_context__update(scripting_context, event, sample, evsel, al, addr_al); + switch (evsel->core.attr.type) { case PERF_TYPE_TRACEPOINT: - python_process_tracepoint(sample, evsel, al); + python_process_tracepoint(sample, evsel, al, addr_al); break; /* Reserve for future process_hw/sw/raw APIs */ default: if (tables->db_export_mode) - db_export__sample(&tables->dbe, event, sample, evsel, al); + db_export__sample(&tables->dbe, event, sample, evsel, al, addr_al); else - python_process_general_event(sample, evsel, al); + python_process_general_event(sample, evsel, al, addr_al); + } +} + +static void python_process_throttle(union perf_event *event, + struct perf_sample *sample, + struct machine *machine) +{ + const char *handler_name; + PyObject *handler, *t; + + if (event->header.type == PERF_RECORD_THROTTLE) + handler_name = "throttle"; + else + handler_name = "unthrottle"; + handler = get_handler(handler_name); + if (!handler) + return; + + t = tuple_new(6); + if (!t) + return; + + tuple_set_u64(t, 0, event->throttle.time); + tuple_set_u64(t, 1, event->throttle.id); + tuple_set_u64(t, 2, event->throttle.stream_id); + tuple_set_s32(t, 3, sample->cpu); + tuple_set_s32(t, 4, sample->pid); + tuple_set_s32(t, 5, sample->tid); + + call_object(handler, t, handler_name); + + Py_DECREF(t); +} + +static void python_do_process_switch(union perf_event *event, + struct perf_sample *sample, + struct machine *machine) +{ + const char *handler_name = "context_switch"; + bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; + bool out_preempt = out && (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT); + pid_t np_pid = -1, np_tid = -1; + PyObject *handler, *t; + + handler = get_handler(handler_name); + if (!handler) + return; + + if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) { + np_pid = event->context_switch.next_prev_pid; + np_tid = event->context_switch.next_prev_tid; } + + t = tuple_new(9); + if (!t) + return; + + tuple_set_u64(t, 0, sample->time); + tuple_set_s32(t, 1, sample->cpu); + tuple_set_s32(t, 2, sample->pid); + tuple_set_s32(t, 3, sample->tid); + tuple_set_s32(t, 4, np_pid); + tuple_set_s32(t, 5, np_tid); + tuple_set_s32(t, 6, machine->pid); + tuple_set_bool(t, 7, out); + tuple_set_bool(t, 8, out_preempt); + + call_object(handler, t, handler_name); + + Py_DECREF(t); } static void python_process_switch(union perf_event *event, @@ -1342,6 +1499,44 @@ static void python_process_switch(union perf_event *event, if (tables->db_export_mode) db_export__switch(&tables->dbe, event, sample, machine); + else + python_do_process_switch(event, sample, machine); +} + +static void python_process_auxtrace_error(struct perf_session *session __maybe_unused, + union perf_event *event) +{ + struct perf_record_auxtrace_error *e = &event->auxtrace_error; + u8 cpumode = e->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + const char *handler_name = "auxtrace_error"; + unsigned long long tm = e->time; + const char *msg = e->msg; + PyObject *handler, *t; + + handler = get_handler(handler_name); + if (!handler) + return; + + if (!e->fmt) { + tm = 0; + msg = (const char *)&e->time; + } + + t = tuple_new(9); + + tuple_set_u32(t, 0, e->type); + tuple_set_u32(t, 1, e->code); + tuple_set_s32(t, 2, e->cpu); + tuple_set_s32(t, 3, e->pid); + tuple_set_s32(t, 4, e->tid); + tuple_set_u64(t, 5, e->ip); + tuple_set_u64(t, 6, tm); + tuple_set_string(t, 7, msg); + tuple_set_u32(t, 8, cpumode); + + call_object(handler, t, handler_name); + + Py_DECREF(t); } static void get_handler_name(char *str, size_t size, @@ -1442,6 +1637,31 @@ static void python_process_stat_interval(u64 tstamp) Py_DECREF(t); } +static int perf_script_context_init(void) +{ + PyObject *perf_script_context; + PyObject *perf_trace_context; + PyObject *dict; + int ret; + + perf_trace_context = PyImport_AddModule("perf_trace_context"); + if (!perf_trace_context) + return -1; + dict = PyModule_GetDict(perf_trace_context); + if (!dict) + return -1; + + perf_script_context = _PyCapsule_New(scripting_context, NULL, NULL); + if (!perf_script_context) + return -1; + + ret = PyDict_SetItemString(dict, "perf_script_context", perf_script_context); + if (!ret) + ret = PyDict_SetItemString(main_dict, "perf_script_context", perf_script_context); + Py_DECREF(perf_script_context); + return ret; +} + static int run_start_sub(void) { main_module = PyImport_AddModule("__main__"); @@ -1454,6 +1674,9 @@ static int run_start_sub(void) goto error; Py_INCREF(main_dict); + if (perf_script_context_init()) + goto error; + try_call_object("trace_begin", NULL); return 0; @@ -1589,7 +1812,8 @@ static void _free_command_line(wchar_t **command_line, int num) /* * Start trace script */ -static int python_start_script(const char *script, int argc, const char **argv) +static int python_start_script(const char *script, int argc, const char **argv, + struct perf_session *session) { struct tables *tables = &tables_global; #if PY_MAJOR_VERSION < 3 @@ -1605,6 +1829,7 @@ static int python_start_script(const char *script, int argc, const char **argv) int i, err = 0; FILE *fp; + scripting_context->session = session; #if PY_MAJOR_VERSION < 3 command_line = malloc((argc + 1) * sizeof(const char *)); command_line[0] = script; @@ -1876,12 +2101,15 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile struct scripting_ops python_scripting_ops = { .name = "Python", + .dirname = "python", .start_script = python_start_script, .flush_script = python_flush_script, .stop_script = python_stop_script, .process_event = python_process_event, .process_switch = python_process_switch, + .process_auxtrace_error = python_process_auxtrace_error, .process_stat = python_process_stat, .process_stat_interval = python_process_stat_interval, + .process_throttle = python_process_throttle, .generate_script = python_generate_script, }; |