static PyObject *
trace_callback(PyObject *self, PyObject *args)
{
- int what;
+ unsigned int what;
PyObject *frame_obj, *arg_obj;
+ unsigned int key;
/* Parse the input tuple */
- if (!PyArg_ParseTuple(args, "iOO", &what, &frame_obj, &arg_obj))
+ if (!PyArg_ParseTuple(args, "IOOI", &what, &frame_obj, &arg_obj, &key))
return NULL;
/* We want to name the probes with the same name as the
case PyTrace_CALL:
#pragma push_macro("PyTrace_CALL")
#undef PyTrace_CALL
- STAP_PROBE2(HelperSDT, PyTrace_CALL, frame_obj, arg_obj);
+ STAP_PROBE3(HelperSDT, PyTrace_CALL, frame_obj, arg_obj, key);
#pragma pop_macro("PyTrace_CALL")
break;
case PyTrace_EXCEPTION:
#pragma push_macro("PyTrace_EXCEPTION")
#undef PyTrace_EXCEPTION
- STAP_PROBE2(HelperSDT, PyTrace_EXCEPTION, frame_obj, arg_obj);
+ STAP_PROBE3(HelperSDT, PyTrace_EXCEPTION, frame_obj, arg_obj, key);
#pragma pop_macro("PyTrace_EXCEPTION")
break;
case PyTrace_LINE:
#pragma push_macro("PyTrace_LINE")
#undef PyTrace_LINE
- STAP_PROBE2(HelperSDT, PyTrace_LINE, frame_obj, arg_obj);
+ STAP_PROBE3(HelperSDT, PyTrace_LINE, frame_obj, arg_obj, key);
#pragma pop_macro("PyTrace_LINE")
break;
case PyTrace_RETURN:
#pragma push_macro("PyTrace_RETURN")
#undef PyTrace_RETURN
- STAP_PROBE2(HelperSDT, PyTrace_RETURN, frame_obj, arg_obj);
+ STAP_PROBE3(HelperSDT, PyTrace_RETURN, frame_obj, arg_obj, key);
#pragma pop_macro("PyTrace_RETURN")
break;
// FIXME: What about PyTrace_C_CALL, PyTrace_C_EXCEPTION,
class _Breakpoint:
- def __init__(self, index, filename, funcname, lineno=None,
- returnp=False):
- # We've got to have a filename and funcname with an optional
- # lineno or returnp.
- if not filename:
- pass
- if not funcname:
- pass
+ def __init__(self, index, filename, funcname, lineno, returnp, key):
self.index = index
self.filename = filename
self.funcname = funcname
self.lineno = lineno
self.returnp = returnp
+ self.key = key
def dump(self, out=None):
if out is None:
disp = self.funcname
else:
disp = '%s.return' % self.funcname
- return '%-4dbreakpoint at %s:%s' % (self.index, self.filename, disp)
+ return '%-4dbreakpoint at %s:%s %d' % (self.index, self.filename,
+ disp, self.key)
class _BreakpointList:
self._byfunc = {} # indexed by (file, function) tuple
self._byfuncret = {} # indexed by (file, function) tuple
- def add(self, filename, funcname, lineno=None, returnp=None):
- bp = _Breakpoint(self._index, filename, funcname, lineno, returnp)
+ def add(self, filename, funcname, lineno, returnp, key):
+ bp = _Breakpoint(self._index, filename, funcname, lineno,
+ returnp, key)
self._index += 1
self._bynumber.append(bp)
if bp.lineno:
% (frame.f_code.co_filename,
frame.f_code.co_name))
_HelperSDT.trace_callback(_HelperSDT.PyTrace_CALL,
- frame, arg)
+ frame, arg, bp.key)
return self.pytrace_dispatch
elif event == 'line':
bplist = self._bplist.break_here(frame, event)
% (frame.f_code.co_filename,
frame.f_code.co_name, frame.f_lineno))
_HelperSDT.trace_callback(_HelperSDT.PyTrace_LINE,
- frame, arg)
+ frame, arg, bp.key)
return self.pytrace_dispatch
elif event == 'return':
bplist = self._bplist.break_here(frame, event)
% (frame.f_code.co_filename,
frame.f_code.co_name, frame.f_lineno))
_HelperSDT.trace_callback(_HelperSDT.PyTrace_RETURN,
- frame, arg)
+ frame, arg, bp.key)
return self.pytrace_dispatch
return self.pytrace_dispatch
def do_b(self, arg):
# Breakpoint command:
- # b [ MODULE|FUNCTION@FILENAME:LINENO|FLAGS ]
+ # b [ MODULE|FUNCTION@FILENAME:LINENO|FLAGS|KEY ]
if not arg:
self._bplist.dump()
return
filename = None
lineno = None
flags = None
+ key = None
parts = arg.split('|')
- if len(parts) != 3:
+ if len(parts) != 4:
sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
- sys.stderr.write("Wrong number of major parts (%d vs. 3)\n" %
+ sys.stderr.write("Wrong number of major parts (%d vs. 4)\n" %
len(parts))
return
# module = parts[0]
sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
sys.stderr.write("Invalid flags value (%s)\n" % parts[2])
return
+ try:
+ key = int(parts[3])
+ except:
+ sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
+ sys.stderr.write("Invalid key value (%s)\n" % parts[3])
+ return
parts = filename_arg.split('@')
if len(parts) != 2:
sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
returnp = True
# Actually add the breakpoint.
- self._bplist.add(filename, funcname, lineno, returnp)
+ self._bplist.add(filename, funcname, lineno, returnp, key)
def run():
// Output the probe info buffer.
if (python2_probes.size())
{
+ unsigned index = 0;
s.op->newline() << "static const char python2_probe_info[] =";
s.op->indent(1);
for (auto iter = python2_probes.begin(); iter != python2_probes.end();
iter++)
{
- s.op->newline() << "\"b " << (*iter)->break_definition() << "\\n\"";
+ s.op->newline() << "\"b " << (*iter)->break_definition()
+ << "|" << index++ << "\\n\"";
}
s.op->line() << ";";
s.op->indent(-1);
}
if (python3_probes.size())
{
+ unsigned index = 0;
s.op->newline() << "static const char python3_probe_info[] =";
s.op->indent(1);
for (auto iter = python3_probes.begin(); iter != python3_probes.end();
iter++)
{
- s.op->newline() << "\"b " << (*iter)->break_definition() << "\\n\"";
+ s.op->newline() << "\"b " << (*iter)->break_definition()
+ << "|" << index++ << "\\n\"";
}
s.op->line() << ";";
s.op->indent(-1);