assert self.spam_func.cname in bp.location
assert bp.enabled
-
+
+ def test_python_break(self):
+ gdb.execute('cy break -p join')
+ assert 'def join(' in gdb.execute('cy run', to_string=True)
+
class DebugStepperTestCase(DebugTestCase):
def step(self, varnames_and_values, source_line=None, lineno=None):
"""
command_class = gdb.COMMAND_NONE
- completer_class = gdb.COMPLETE_NONE
@classmethod
def _register(cls, clsname, args, kwargs):
or for a line number:
cy break cython_module:lineno...
+
+ Set a Python breakpoint:
+ Break on any function or method named 'func' in module 'modname'
+
+ cy break -p modname.func...
+
+ Break on any function or method named 'func'
+
+ cy break -p func...
"""
name = 'cy break'
gdb.execute('break %s' % func.pf_cname)
def invoke(self, function_names, from_tty):
- for funcname in string_to_argv(function_names.encode('UTF-8')):
- if ':' in funcname:
+ argv = string_to_argv(function_names.encode('UTF-8'))
+ if function_names.startswith('-p'):
+ argv = argv[1:]
+ python_breakpoints = True
+ else:
+ python_breakpoints = False
+
+ for funcname in argv:
+ if python_breakpoints:
+ gdb.execute('py-break %s' % funcname)
+ elif ':' in funcname:
self._break_pyx(funcname)
else:
self._break_funcname(funcname)
PyGlobals("py-globals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
+class PyNameEquals(gdb.Function):
+
+ def _get_pycurframe_attr(self, attr):
+ frame = Frame(gdb.selected_frame())
+ if frame.is_evalframeex():
+ pyframe = frame.get_pyop()
+ if pyframe is None:
+ return None
+
+ return str(getattr(pyframe, attr))
+
+ return None
+
+ def invoke(self, funcname):
+ attr = self._get_pycurframe_attr('co_name')
+ return attr is not None and attr == funcname.string()
+
+PyNameEquals("pyname_equals")
+
+
+class PyModEquals(PyNameEquals):
+
+ def invoke(self, modname):
+ attr = self._get_pycurframe_attr('co_filename')
+ if attr is not None:
+ filename, ext = os.path.splitext(os.path.basename(attr))
+ return filename == modname.string()
+ return False
+
+PyModEquals("pymod_equals")
+
+
+class PyBreak(gdb.Command):
+ """
+ Set a Python breakpoint. Examples:
+
+ Break on any function or method named 'func' in module 'modname'
+
+ py-break modname.func
+
+ Break on any function or method named 'func'
+
+ py-break func
+ """
+
+ def invoke(self, funcname, from_tty):
+ if '.' in funcname:
+ modname, dot, funcname = funcname.rpartition('.')
+ cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname,
+ modname)
+ else:
+ cond = '$pyname_equals("%s")' % funcname
+
+ gdb.execute('break PyEval_EvalFrameEx if ' + cond)
+
+PyBreak("py-break", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE)
+
+
class _LoggingState(object):
"""
State that helps to provide a reentrant gdb.execute() function.