Support dereferencing variables in Cython frames
authorMark Florisson <markflorisson88@gmail.com>
Sat, 6 Nov 2010 22:56:59 +0000 (23:56 +0100)
committerMark Florisson <markflorisson88@gmail.com>
Sat, 6 Nov 2010 22:56:59 +0000 (23:56 +0100)
Set pretty printing of C structs on by default
Export the 'cname' of 'self' local variables in the XML debug info properly

Cython/Compiler/ParseTreeTransforms.py
Cython/Debugger/Cygdb.py
Cython/Debugger/Tests/test_libcython_in_gdb.py
Cython/Debugger/libcython.py

index bc3514b3113f97dc4454e998e28047f6a6988f6b..1e00d50de7e0d93eed13558b4fcc52c36c7191ba 100644 (file)
@@ -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,
index 6045659b4781ed8ac2523cb097893148b1bd5055..4c83c2c0daadf5324a65fcb6d3169823fde6faf4 100644 (file)
@@ -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))
index d9c3a068ab169677ef71a27a406ac5816a0625e8..c33739147b58d0ff04a363646864f8abb8cfcce9 100644 (file)
@@ -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):
index b1beca5c71687905ecb5bb4c0d223409cfc5d066..02c220abea584a3d8e31d548eb99690ae2589a86 100644 (file)
@@ -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)