From e325fbee725fa21eb49941ad84ac49bfccf11021 Mon Sep 17 00:00:00 2001 From: Mark Florisson Date: Tue, 14 Dec 2010 23:51:04 +0100 Subject: [PATCH] Detect Python exceptions --- Cython/Debugger/libcython.py | 9 +++++--- Cython/Debugger/libpython.py | 42 +++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Cython/Debugger/libcython.py b/Cython/Debugger/libcython.py index 8d55f01a..7d2a7320 100644 --- a/Cython/Debugger/libcython.py +++ b/Cython/Debugger/libcython.py @@ -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 diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py index c83d7ddf..75c78505 100644 --- a/Cython/Debugger/libpython.py +++ b/Cython/Debugger/libpython.py @@ -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('' % (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' -- 2.26.2