Detect Python exceptions
authorMark Florisson <markflorisson88@gmail.com>
Tue, 14 Dec 2010 22:51:04 +0000 (23:51 +0100)
committerMark Florisson <markflorisson88@gmail.com>
Tue, 14 Dec 2010 22:51:04 +0000 (23:51 +0100)
Cython/Debugger/libcython.py
Cython/Debugger/libpython.py

index 8d55f01a52fd5c1c69c00165568445bd33c8413e..7d2a7320ef2c7b142e07c1a40a06ca747f2c1cbe 100644 (file)
@@ -835,7 +835,7 @@ class CyBreak(CythonCommand):
         return compl
 
 
-class CythonInfo(CythonBase, libpython.LanguageInfo):
+class CythonInfo(CythonBase, libpython.PythonInfo):
     """
     Implementation of the interface dictated by libpython.LanguageInfo.
     """
@@ -847,8 +847,7 @@ class CythonInfo(CythonBase, libpython.LanguageInfo):
         # related code. The C level should be dispatched to the 'step' command.
         if self.is_cython_function(frame):
             return self.get_cython_lineno(frame)
-        else:
-            return libpython.py_step.lang_info.lineno(frame)
+        return super(CythonInfo, self).lineno(frame)
     
     def get_source_line(self, frame):
         try:
@@ -858,6 +857,10 @@ class CythonInfo(CythonBase, libpython.LanguageInfo):
         else:
             return line.strip() or None
 
+    def exc_info(self, frame):
+        if self.is_python_function:
+            return super(CythonInfo, self).exc_info(frame)
+
     def runtime_break_functions(self):
         if self.is_cython_function():
             return self.get_cython_function().step_into_functions
index c83d7ddf3f32714404c3daa7e58bbd9e805d4120..75c785056ab19567cae545e9c11af63c6de7682e 100644 (file)
@@ -369,8 +369,8 @@ class PyObjectPtr(object):
         if tp_name in name_map:
             return name_map[tp_name]
         
-        if tp_flags & Py_TPFLAGS_HEAPTYPE:
-            return HeapTypeObjectPtr
+        if tp_flags & (Py_TPFLAGS_HEAPTYPE|Py_TPFLAGS_TYPE_SUBCLASS):
+            return PyTypeObjectPtr
 
         if tp_flags & Py_TPFLAGS_INT_SUBCLASS:
             return PyIntObjectPtr
@@ -392,8 +392,6 @@ class PyObjectPtr(object):
             return PyDictObjectPtr
         if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
             return PyBaseExceptionObjectPtr
-        #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
-        #    return PyTypeObjectPtr
 
         # Use the base class:
         return cls
@@ -484,8 +482,8 @@ def _PyObject_VAR_SIZE(typeobj, nitems):
              ) & ~(SIZEOF_VOID_P - 1)
            ).cast(gdb.lookup_type('size_t'))
 
-class HeapTypeObjectPtr(PyObjectPtr):
-    _typename = 'PyObject'
+class PyTypeObjectPtr(PyObjectPtr):
+    _typename = 'PyTypeObject'
     
     def get_attr_dict(self):
         '''
@@ -545,10 +543,17 @@ class HeapTypeObjectPtr(PyObjectPtr):
             out.write('<...>')
             return
         visited.add(self.as_address())
-
-        pyop_attrdict = self.get_attr_dict()
-        _write_instance_repr(out, visited,
-                             self.safe_tp_name(), pyop_attrdict, self.as_address())
+        
+        try:
+            tp_name = self.field('tp_name').string()
+        except RuntimeError:
+            tp_name = 'unknown'
+        
+        out.write('<type %s at remote 0x%x>' % (tp_name, 
+                                                self.as_address()))
+        # pyop_attrdict = self.get_attr_dict()
+        # _write_instance_repr(out, visited,
+                             # self.safe_tp_name(), pyop_attrdict, self.as_address())
 
 class ProxyException(Exception):
     def __init__(self, tp_name, args):
@@ -1136,9 +1141,6 @@ class PyTupleObjectPtr(PyObjectPtr):
         else:
             out.write(')')
 
-class PyTypeObjectPtr(PyObjectPtr):
-    _typename = 'PyTypeObject'
-
 
 def _unichr_is_printable(char):
     # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
@@ -2171,6 +2173,20 @@ class PythonInfo(LanguageInfo):
         except IOError, e:
             return None
     
+    def exc_info(self, frame):
+        try:
+            tstate = frame.read_var('tstate').dereference()
+            if gdb.parse_and_eval('tstate->frame == f'):
+                # tstate local variable initialized
+                inf_type = tstate['curexc_type']
+                inf_value = tstate['curexc_value']
+                if inf_type:
+                    return 'An exception was raised: %s(%s)' % (inf_type, 
+                                                                inf_value)
+        except (ValueError, RuntimeError), e:
+            # Could not read the variable tstate or it's memory, it's ok
+            pass
+        
     def static_break_functions(self):
         yield 'PyEval_EvalFrameEx'