summaryrefslogtreecommitdiff
path: root/Cython/Debugger/libpython.py
diff options
context:
space:
mode:
authorMark Florisson <markflorisson88@gmail.com>2010-11-11 13:16:21 +0100
committerMark Florisson <markflorisson88@gmail.com>2010-11-11 13:16:21 +0100
commitad032f3f48b32e37035ebc5926bbfc5a8265dbf7 (patch)
tree6638c0e66af9928f09d3e58aefc5fa41898ae5a2 /Cython/Debugger/libpython.py
parent8977d45bae7a1e1b2d3908c7783f7f78c4f7d46d (diff)
downloadcython-ad032f3f48b32e37035ebc5926bbfc5a8265dbf7.tar.gz
Add 'cy finish', 'py-finish', 'py-run' and 'py-cont' commands.
Diffstat (limited to 'Cython/Debugger/libpython.py')
-rw-r--r--Cython/Debugger/libpython.py133
1 files changed, 97 insertions, 36 deletions
diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py
index fb51cda44..7a5572e07 100644
--- a/Cython/Debugger/libpython.py
+++ b/Cython/Debugger/libpython.py
@@ -1686,6 +1686,72 @@ class GenericCodeStepper(gdb.Command):
context.
"""
+ def stopped(self):
+ return gdb.inferiors()[0].pid == 0
+
+ def _stackdepth(self, frame):
+ depth = 0
+ while frame:
+ frame = frame.older()
+ depth += 1
+
+ return depth
+
+ def finish_executing(self, result):
+ """
+ After doing some kind of code running in the inferior, print the line
+ of source code or the result of the last executed gdb command (passed
+ in as the `result` argument).
+ """
+ if self.stopped():
+ print result.strip()
+ else:
+ frame = gdb.selected_frame()
+ output = None
+
+ if self.is_relevant_function(frame):
+ output = self.get_source_line(frame)
+
+ if output is None:
+ pframe = getattr(self, 'print_stackframe', None)
+ if pframe:
+ pframe(frame, index=0)
+ else:
+ print result.strip()
+ else:
+ print output
+
+ def _finish(self):
+ """
+ Execute until the function returns (or until something else makes it
+ stop)
+ """
+ if gdb.selected_frame().older() is not None:
+ return gdb.execute('finish', to_string=True)
+ else:
+ # outermost frame, continue
+ return gdb.execute('cont', to_string=True)
+
+ def finish(self, *args):
+ """
+ Execute until the function returns to a relevant caller.
+ """
+
+ while True:
+ result = self._finish()
+
+ try:
+ frame = gdb.selected_frame()
+ except RuntimeError:
+ break
+
+ hitbp = re.search(r'Breakpoint (\d+)', result)
+ is_relavant = self.is_relevant_function(frame)
+ if hitbp or is_relavant or self.stopped():
+ break
+
+ self.finish_executing(result)
+
def _step(self):
"""
Do a single step or step-over. Returns the result of the last gdb
@@ -1706,10 +1772,7 @@ class GenericCodeStepper(gdb.Command):
if self.is_relevant_function(newframe):
result = gdb.execute('next', to_string=True)
else:
- if self._stackdepth(newframe) == 1:
- result = gdb.execute('cont', to_string=True)
- else:
- result = gdb.execute('finish', to_string=True)
+ result = self._finish()
if self.stopped():
break
@@ -1749,39 +1812,15 @@ class GenericCodeStepper(gdb.Command):
self.disable_breakpoints()
return result
-
- def stopped(self):
- return gdb.inferiors()[0].pid == 0
-
- def _stackdepth(self, frame):
- depth = 0
- while frame:
- frame = frame.older()
- depth += 1
-
- return depth
- def invoke(self, args, from_tty):
- self.finish_executing(self._step())
+ def step(self):
+ return self.finish_executing(self._step())
+
+ def run(self, *args):
+ self.finish_executing(gdb.execute('run', to_string=True))
- def finish_executing(self, result):
- if self.stopped():
- print result.strip()
- else:
- frame = gdb.selected_frame()
- output = None
-
- if self.is_relevant_function(frame):
- output = self.get_source_line(frame)
-
- if output is None:
- pframe = getattr(self, 'print_stackframe', None)
- if pframe:
- pframe(frame, index=0)
- else:
- print result.strip()
- else:
- print output
+ def cont(self, *args):
+ self.finish_executing(gdb.execute('cont', to_string=True))
class PythonCodeStepper(GenericCodeStepper):
@@ -1813,11 +1852,33 @@ class PythonCodeStepper(GenericCodeStepper):
class PyStep(PythonCodeStepper):
"Step through Python code."
-
+
+ invoke = PythonCodeStepper.step
+
class PyNext(PythonCodeStepper):
"Step-over Python code."
+
+ invoke = PythonCodeStepper.step
+
+class PyFinish(PythonCodeStepper):
+ "Execute until function returns to a caller."
+
+ invoke = PythonCodeStepper.finish
+
+class PyRun(PythonCodeStepper):
+ "Run the program."
+
+ invoke = PythonCodeStepper.run
+
+class PyCont(PythonCodeStepper):
+
+ invoke = PythonCodeStepper.cont
+
py_step = PyStep('py-step', stepinto=True)
py_next = PyNext('py-next', stepinto=False)
+py_finish = PyFinish('py-finish')
+py_run = PyRun('py-run')
+py_cont = PyCont('py-cont')
py_step.init_breakpoints() \ No newline at end of file