0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define PY_SSIZE_T_CLEAN
0013
0014 #include <Python.h>
0015 #include "../../../util/trace-event.h"
0016 #include "../../../util/event.h"
0017 #include "../../../util/symbol.h"
0018 #include "../../../util/thread.h"
0019 #include "../../../util/map.h"
0020 #include "../../../util/maps.h"
0021 #include "../../../util/auxtrace.h"
0022 #include "../../../util/session.h"
0023 #include "../../../util/srcline.h"
0024 #include "../../../util/srccode.h"
0025
0026 #if PY_MAJOR_VERSION < 3
0027 #define _PyCapsule_GetPointer(arg1, arg2) \
0028 PyCObject_AsVoidPtr(arg1)
0029 #define _PyBytes_FromStringAndSize(arg1, arg2) \
0030 PyString_FromStringAndSize((arg1), (arg2))
0031 #define _PyUnicode_AsUTF8(arg) \
0032 PyString_AsString(arg)
0033
0034 PyMODINIT_FUNC initperf_trace_context(void);
0035 #else
0036 #define _PyCapsule_GetPointer(arg1, arg2) \
0037 PyCapsule_GetPointer((arg1), (arg2))
0038 #define _PyBytes_FromStringAndSize(arg1, arg2) \
0039 PyBytes_FromStringAndSize((arg1), (arg2))
0040 #define _PyUnicode_AsUTF8(arg) \
0041 PyUnicode_AsUTF8(arg)
0042
0043 PyMODINIT_FUNC PyInit_perf_trace_context(void);
0044 #endif
0045
0046 static struct scripting_context *get_args(PyObject *args, const char *name, PyObject **arg2)
0047 {
0048 int cnt = 1 + !!arg2;
0049 PyObject *context;
0050
0051 if (!PyArg_UnpackTuple(args, name, 1, cnt, &context, arg2))
0052 return NULL;
0053
0054 return _PyCapsule_GetPointer(context, NULL);
0055 }
0056
0057 static struct scripting_context *get_scripting_context(PyObject *args)
0058 {
0059 return get_args(args, "context", NULL);
0060 }
0061
0062 static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
0063 {
0064 struct scripting_context *c = get_scripting_context(args);
0065
0066 if (!c)
0067 return NULL;
0068
0069 return Py_BuildValue("i", common_pc(c));
0070 }
0071
0072 static PyObject *perf_trace_context_common_flags(PyObject *obj,
0073 PyObject *args)
0074 {
0075 struct scripting_context *c = get_scripting_context(args);
0076
0077 if (!c)
0078 return NULL;
0079
0080 return Py_BuildValue("i", common_flags(c));
0081 }
0082
0083 static PyObject *perf_trace_context_common_lock_depth(PyObject *obj,
0084 PyObject *args)
0085 {
0086 struct scripting_context *c = get_scripting_context(args);
0087
0088 if (!c)
0089 return NULL;
0090
0091 return Py_BuildValue("i", common_lock_depth(c));
0092 }
0093
0094 static PyObject *perf_sample_insn(PyObject *obj, PyObject *args)
0095 {
0096 struct scripting_context *c = get_scripting_context(args);
0097
0098 if (!c)
0099 return NULL;
0100
0101 if (c->sample->ip && !c->sample->insn_len &&
0102 c->al->thread->maps && c->al->thread->maps->machine)
0103 script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine);
0104
0105 if (!c->sample->insn_len)
0106 Py_RETURN_NONE;
0107
0108 return _PyBytes_FromStringAndSize(c->sample->insn, c->sample->insn_len);
0109 }
0110
0111 static PyObject *perf_set_itrace_options(PyObject *obj, PyObject *args)
0112 {
0113 struct scripting_context *c;
0114 const char *itrace_options;
0115 int retval = -1;
0116 PyObject *str;
0117
0118 c = get_args(args, "itrace_options", &str);
0119 if (!c)
0120 return NULL;
0121
0122 if (!c->session || !c->session->itrace_synth_opts)
0123 goto out;
0124
0125 if (c->session->itrace_synth_opts->set) {
0126 retval = 1;
0127 goto out;
0128 }
0129
0130 itrace_options = _PyUnicode_AsUTF8(str);
0131
0132 retval = itrace_do_parse_synth_opts(c->session->itrace_synth_opts, itrace_options, 0);
0133 out:
0134 return Py_BuildValue("i", retval);
0135 }
0136
0137 static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode)
0138 {
0139 struct scripting_context *c = get_scripting_context(args);
0140 unsigned int line = 0;
0141 char *srcfile = NULL;
0142 char *srccode = NULL;
0143 PyObject *result;
0144 struct map *map;
0145 int len = 0;
0146 u64 addr;
0147
0148 if (!c)
0149 return NULL;
0150
0151 map = c->al->map;
0152 addr = c->al->addr;
0153
0154 if (map && map->dso)
0155 srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line);
0156
0157 if (get_srccode) {
0158 if (srcfile)
0159 srccode = find_sourceline(srcfile, line, &len);
0160 result = Py_BuildValue("(sIs#)", srcfile, line, srccode, (Py_ssize_t)len);
0161 } else {
0162 result = Py_BuildValue("(sI)", srcfile, line);
0163 }
0164
0165 free(srcfile);
0166
0167 return result;
0168 }
0169
0170 static PyObject *perf_sample_srcline(PyObject *obj, PyObject *args)
0171 {
0172 return perf_sample_src(obj, args, false);
0173 }
0174
0175 static PyObject *perf_sample_srccode(PyObject *obj, PyObject *args)
0176 {
0177 return perf_sample_src(obj, args, true);
0178 }
0179
0180 static PyMethodDef ContextMethods[] = {
0181 { "common_pc", perf_trace_context_common_pc, METH_VARARGS,
0182 "Get the common preempt count event field value."},
0183 { "common_flags", perf_trace_context_common_flags, METH_VARARGS,
0184 "Get the common flags event field value."},
0185 { "common_lock_depth", perf_trace_context_common_lock_depth,
0186 METH_VARARGS, "Get the common lock depth event field value."},
0187 { "perf_sample_insn", perf_sample_insn,
0188 METH_VARARGS, "Get the machine code instruction."},
0189 { "perf_set_itrace_options", perf_set_itrace_options,
0190 METH_VARARGS, "Set --itrace options."},
0191 { "perf_sample_srcline", perf_sample_srcline,
0192 METH_VARARGS, "Get source file name and line number."},
0193 { "perf_sample_srccode", perf_sample_srccode,
0194 METH_VARARGS, "Get source file name, line number and line."},
0195 { NULL, NULL, 0, NULL}
0196 };
0197
0198 #if PY_MAJOR_VERSION < 3
0199 PyMODINIT_FUNC initperf_trace_context(void)
0200 {
0201 (void) Py_InitModule("perf_trace_context", ContextMethods);
0202 }
0203 #else
0204 PyMODINIT_FUNC PyInit_perf_trace_context(void)
0205 {
0206 static struct PyModuleDef moduledef = {
0207 PyModuleDef_HEAD_INIT,
0208 "perf_trace_context",
0209 "",
0210 -1,
0211 ContextMethods,
0212 NULL,
0213 NULL,
0214 NULL,
0215 NULL,
0216 };
0217 PyObject *mod;
0218
0219 mod = PyModule_Create(&moduledef);
0220
0221 PyObject_SetAttrString(mod, "perf_script_context", Py_None);
0222
0223 return mod;
0224 }
0225 #endif