Commit 3aec761b authored by Mark Florisson's avatar Mark Florisson

Support dereferencing variables in Cython frames

Set pretty printing of C structs on by default
Export the 'cname' of 'self' local variables in the XML debug info properly
parent 42fea3e8
......@@ -1577,8 +1577,8 @@ class DebugTransform(CythonTransform):
vartype = 'CObject'
cname = entry.cname
if entry.type.is_extension_type:
cname = entry.type.typeptr_cname
# if entry.type.is_extension_type:
# cname = entry.type.typeptr_cname
attrs = dict(
name=entry.name,
......
......@@ -35,6 +35,7 @@ def make_command_file(path_to_debug_info, prefix_code='', no_import=False):
f = os.fdopen(fd, 'w')
f.write(prefix_code)
f.write('set breakpoint pending on\n')
f.write("set print pretty on\n")
f.write('python from Cython.Debugger import libcython\n')
if not no_import:
f.write('\n'.join('cy import %s\n' % fn for fn in debug_files))
......
......@@ -215,9 +215,9 @@ class TestLocalsGlobals(DebugTestCase):
self.break_and_run('int(10)')
result = gdb.execute('cy locals', to_string=True)
assert 'a = 0' in result, repr(result)
assert 'b = 1' in result, repr(result)
assert 'c = 2' in result, repr(result)
assert 'a = 0', repr(result)
assert 'b = (int) 1', result
assert 'c = (int) 2' in result, repr(result)
def test_globals(self):
self.break_and_run('int(10)')
......@@ -268,7 +268,7 @@ class TestPrint(DebugTestCase):
def test_print(self):
self.break_and_run('c = 2')
result = gdb.execute('cy print b', to_string=True)
assert '= 1' in result
self.assertEqual('b = (int) 1\n', result)
class TestUpDown(DebugTestCase):
......
......@@ -367,6 +367,19 @@ class CythonBase(object):
return result
def print_gdb_value(self, name, value, max_name_length=None, prefix=''):
if libpython.pretty_printer_lookup(value):
typename = ''
else:
typename = '(%s) ' % (value.type,)
if max_name_length is None:
print '%s%s = %s%s' % (prefix, name, typename, value)
else:
print '%s%-*s = %s%s' % (prefix, max_name_length, name, typename,
value)
class SourceFileDescriptor(object):
def __init__(self, filename, lexer, formatter=None):
self.filename = filename
......@@ -977,11 +990,14 @@ class CyPrint(CythonCommand):
if self.is_python_function():
return gdb.execute('py-print ' + name)
elif self.is_cython_function():
value = self.cy.cy_cvalue.invoke(name)
if max_name_length is None:
print '%s = %s' % (name, value)
else:
print '%-*s = %s' % (max_name_length, name, value)
value = self.cy.cy_cvalue.invoke(name.lstrip('*'))
for c in name:
if c == '*':
value = value.dereference()
else:
break
self.print_gdb_value(name, value, max_name_length)
else:
gdb.execute('print ' + name)
......@@ -1011,7 +1027,7 @@ class CyLocals(CythonCommand):
# variable not initialized yet
pass
else:
print '%s%-*s = %s' % (prefix, max_name_length, cyvar.name, value)
self.print_gdb_value(cyvar.name, value, max_name_length, prefix)
@dispatch_on_frame(c_command='info locals', python_command='py-locals')
def invoke(self, args, from_tty):
......@@ -1104,18 +1120,16 @@ class CyCValue(CyCName):
@require_cython_frame
@gdb_function_value_to_unicode
def invoke(self, cyname, frame=None):
cname = super(CyCValue, self).invoke(cyname, frame=frame)
try:
cname = super(CyCValue, self).invoke(cyname, frame=frame)
return gdb.parse_and_eval(cname)
except RuntimeError:
except (gdb.GdbError, RuntimeError):
# variable exists but may not have been initialized yet, or may be
# in the globals dict of the Cython module
if cyname in self.get_cython_function().module.globals:
# look in the global dict
d = self.get_cython_globals_dict()
if cyname in d:
return d[cyname]._gdbval
# print cyname, self.get_cython_function().module.globals, '\n', self.get_cython_globals_dict()
d = self.get_cython_globals_dict()
if cyname in d:
return d[cyname]._gdbval
raise gdb.GdbError("Variable %s not initialized yet." % cyname)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment