summaryrefslogtreecommitdiff
path: root/Cython/Debugger/libpython.py
diff options
context:
space:
mode:
authorMark Florisson <markflorisson88@gmail.com>2011-01-25 21:41:31 +0100
committerMark Florisson <markflorisson88@gmail.com>2011-01-25 21:41:31 +0100
commitb0f6eba4f3e05b53f4f81feebe8993e651c79806 (patch)
tree38e8f0ea5de310bdfa854055632d53b283af77b1 /Cython/Debugger/libpython.py
parentae137ef75a77f539f501c1d718f9effa710621e8 (diff)
downloadcython-b0f6eba4f3e05b53f4f81feebe8993e651c79806.tar.gz
Debugger: Fix a few libpython.py bugs
Diffstat (limited to 'Cython/Debugger/libpython.py')
-rw-r--r--Cython/Debugger/libpython.py59
1 files changed, 48 insertions, 11 deletions
diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py
index 78534a490..4729412ca 100644
--- a/Cython/Debugger/libpython.py
+++ b/Cython/Debugger/libpython.py
@@ -1322,6 +1322,16 @@ class PyUnicodeObjectPtr(PyObjectPtr):
out.write(quote)
+ def __unicode__(self):
+ return self.proxyval(set())
+
+ def __str__(self):
+ # In Python 3, everything is unicode (including attributes of e.g.
+ # code objects, such as function names). The Python 2 debugger code
+ # uses PyUnicodePtr objects to format strings etc, whereas with a
+ # Python 2 debuggee we'd get PyStringObjectPtr instances with __str__.
+ # Be compatible with that.
+ return unicode(self).encode('UTF-8')
def int_from_int(gdbval):
return int(str(gdbval))
@@ -1452,12 +1462,39 @@ class Frame(object):
return False
+ def read_var(self, varname):
+ """
+ read_var with respect to code blocks (gdbframe.read_var works with
+ respect to the most recent block)
+
+ Apparently this function doesn't work, though, as it seems to read
+ variables in other frames also sometimes.
+ """
+ block = self._gdbframe.block()
+ var = None
+
+ while block and var is None:
+ try:
+ var = self._gdbframe.read_var(varname, block)
+ except ValueError:
+ pass
+
+ block = block.superblock
+
+ return var
+
def get_pyop(self):
try:
- f = self._gdbframe.read_var('f')
- return PyFrameObjectPtr.from_pyobject_ptr(f)
- except ValueError:
+ # self.read_var does not always work properly, so select our frame
+ # and restore the previously selected frame
+ selected_frame = gdb.selected_frame()
+ self._gdbframe.select()
+ f = gdb.parse_and_eval('f')
+ selected_frame.select()
+ except RuntimeError:
return None
+ else:
+ return PyFrameObjectPtr.from_pyobject_ptr(f)
@classmethod
def get_selected_frame(cls):
@@ -2174,9 +2211,10 @@ class PythonStepperMixin(object):
"""
def python_step(self, stepinto):
- frame = gdb.selected_frame()
- framewrapper = Frame(frame)
-
+ """
+ Set a watchpoint on the Python bytecode instruction pointer and try
+ to finish the frame
+ """
output = gdb.execute('watch f->f_lasti', to_string=True)
watchpoint = int(re.search(r'[Ww]atchpoint (\d+):', output).group(1))
self.step(stepinto=stepinto, stepover_command='finish')
@@ -2392,10 +2430,9 @@ class FixGdbCommand(gdb.Command):
def fix_gdb(self):
"""
- So, you must be wondering what the story is this time! Yeeees, indeed,
- I have quite the story for you! It seems that invoking either 'cy exec'
- and 'py-exec' work perfectly fine, but after this gdb's python API is
- entirely broken. Some unset exception value is still set?
+ It seems that invoking either 'cy exec' and 'py-exec' work perfectly
+ fine, but after this gdb's python API is entirely broken.
+ Maybe some uncleared exception value is still set?
sys.exc_clear() didn't help. A demonstration:
(gdb) cy exec 'hello'
@@ -2443,7 +2480,7 @@ class PyExec(gdb.Command):
lines.append(line)
- return '\n'.join(lines), Py_file_input
+ return '\n'.join(lines), PythonCodeExecutor.Py_file_input
def invoke(self, expr, from_tty):
expr, input_type = self.readcode(expr)