Lex only the lines of code that are displayed in a traceback
authorMark Florisson <markflorisson88@gmail.com>
Sun, 7 Nov 2010 22:17:23 +0000 (23:17 +0100)
committerMark Florisson <markflorisson88@gmail.com>
Sun, 7 Nov 2010 22:17:23 +0000 (23:17 +0100)
Have Cython write the sys.executable used to build extensions and have cygdb default the 'file' to that

Cython/Debugger/Cygdb.py
Cython/Debugger/DebugWriter.py
Cython/Debugger/libcython.py
Cython/Debugger/libpython.py

index 09906675d2629c147861d4fa30a82ce6bee5e462..9baa82c47f756b437791e6a985f4f0002521612d 100644 (file)
@@ -30,16 +30,24 @@ def make_command_file(path_to_debug_info, prefix_code='', no_import=False):
             usage()
             sys.exit('No debug files were found in %s. Aborting.' % (
                     os.path.abspath(path_to_debug_info)))
-        
+    
+    
+    
     fd, tempfilename = tempfile.mkstemp()
     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("file %s\n" % sys.executable)
     f.write('python from Cython.Debugger import libcython\n')
-    if not no_import:
+    
+    if no_import:
+        f.write("file %s\n" % sys.executable)
+    else:
+        path = os.path.join(path_to_debug_info, "cython_debug", "interpreter")
+        interpreter = open(path).read()
+        f.write("file %s\n" % interpreter)
         f.write('\n'.join('cy import %s\n' % fn for fn in debug_files))
+    
     f.close()
     
     return tempfilename
index 32e57fb02300a0d4695731e3b695bc1b0902e0a8..5fffb9a13fa02a7c2476fb8c63a79f07e1b17367 100644 (file)
@@ -1,4 +1,5 @@
 import os
+import sys
 import errno
 
 try:
@@ -69,3 +70,7 @@ class CythonDebugWriter(object):
         
         fn = "cython_debug_info_" + self.module_name
         et.write(os.path.join(self.output_dir, fn), encoding="UTF-8", **kw)
+        
+        interpreter_path = os.path.join(self.output_dir, 'interpreter')
+        with open(interpreter_path, 'w') as f:
+            f.write(sys.executable)
index c0558dacc4e472ee7455a5989109e87940dffe7d..b0fa9313c7b560f6efce3f64a4373e2035de3e4b 100644 (file)
@@ -323,9 +323,13 @@ class CythonBase(object):
             func_cname = func_name
             func_args = []
         
-        gdb_value = gdb.parse_and_eval(func_cname)
-        # Seriously? Why is the address not an int?
-        func_address = int(str(gdb_value.address).split()[0], 0)
+        try:
+            gdb_value = gdb.parse_and_eval(func_cname)
+        except RuntimeError:
+            func_address = 0
+        else:
+            # Seriously? Why is the address not an int?
+            func_address = int(str(gdb_value.address).split()[0], 0)
         
         a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
         print '#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a),
@@ -400,25 +404,30 @@ class SourceFileDescriptor(object):
 
         return code
 
-    def _get_source(self, start, stop, lex_source, mark_line):
+    def _get_source(self, start, stop, lex_source, mark_line, lex_entire):
         with open(self.filename) as f:
-            if lex_source:
-                # to provide proper colouring, the entire code needs to be
-                # lexed
-                lines = self.lex(f.read()).splitlines()
-            else:
-                lines = f
-                
-            slice = itertools.islice(lines, start - 1, stop - 1)
+            # to provide "correct" colouring, the entire code needs to be
+            # lexed. However, this makes a lot of things terribly slow, so
+            # we decide not to. Besides, it's unlikely to matter.
+            
+            if lex_source and lex_entire:
+                f = self.lex(f.read()).splitlines()
+            
+            slice = itertools.islice(f, start - 1, stop - 1)
+            
             for idx, line in enumerate(slice):
                 if start + idx == mark_line:
                     prefix = '>'
                 else:
                     prefix = ' '
                 
-                yield '%s %4d    %s' % (prefix, start + idx, line)
+                if lex_source and not lex_entire:
+                    line = self.lex(line)
+
+                yield '%s %4d    %s' % (prefix, start + idx, line.rstrip())
 
-    def get_source(self, start, stop=None, lex_source=True, mark_line=0):
+    def get_source(self, start, stop=None, lex_source=True, mark_line=0, 
+                   lex_entire=False):
         exc = gdb.GdbError('Unable to retrieve source code')
         
         if not self.filename:
@@ -430,7 +439,7 @@ class SourceFileDescriptor(object):
 
         try:
             return '\n'.join(
-                self._get_source(start, stop, lex_source, mark_line))
+                self._get_source(start, stop, lex_source, mark_line, lex_entire))
         except IOError:
             raise exc
 
@@ -985,7 +994,8 @@ class CyList(CythonCommand):
     @dispatch_on_frame(c_command='list')
     def invoke(self, _, from_tty):
         sd, lineno = self.get_source_desc()
-        source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno)
+        source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno, 
+                               lex_entire=True)
         print source
 
 
index 82631716b03bd291df02d2cc006952842db82a20..6d21264465f52fd3c5a63cf1abefba4f888003c9 100644 (file)
@@ -796,7 +796,7 @@ class PyNoneStructPtr(PyObjectPtr):
 class PyFrameObjectPtr(PyObjectPtr):
     _typename = 'PyFrameObject'
 
-    def __init__(self, gdbval, cast_to):
+    def __init__(self, gdbval, cast_to=None):
         PyObjectPtr.__init__(self, gdbval, cast_to)
 
         if not self.is_optimized_out():