except RuntimeError:
pass
+ gdb.execute('set args -c "import codefile"')
+
libcython.cy.step.static_breakpoints.clear()
libcython.cy.step.runtime_breakpoints.clear()
libcython.cy.step.init_breakpoints()
assert 'def join(' in gdb.execute('cy run', to_string=True)
+class TestKilled(DebugTestCase):
+
+ def test_abort(self):
+ gdb.execute("set args -c 'import os; os.abort()'")
+ output = gdb.execute('cy run', to_string=True)
+ assert 'abort' in output.lower()
+
class DebugStepperTestCase(DebugTestCase):
def step(self, varnames_and_values, source_line=None, lineno=None):
"debugging information. Either compile python with "
"-g or get a debug build (configure with --with-pydebug).")
warnings.warn(msg)
+ os._exit(1)
else:
m = __import__(__name__, fromlist=[''])
tests = inspect.getmembers(m, inspect.isclass)
ignoredirs=[sys.prefix, sys.exec_prefix])
tracer.runfunc(_main)
else:
- _main()
\ No newline at end of file
+ _main()
+
+main()
\ No newline at end of file
def is_initialized(self, cython_func, local_name):
cur_lineno = self.get_cython_lineno()
- return (local_name in cython_func.arguments or
- cur_lineno > cython_func.locals[local_name].lineno)
+ return (local_name in cython_func.arguments or
+ (local_name in cython_func.locals and
+ cur_lineno > cython_func.locals[local_name].lineno))
class SourceFileDescriptor(object):
def __init__(self, filename, lexer, formatter=None):
command_class = gdb.COMMAND_STACK
completer_class = gdb.COMPLETE_NONE
- def _print_if_initialized(self, cyvar, max_name_length, prefix=''):
- if self.is_initialized(self.get_cython_function(), cyvar.name):
- value = gdb.parse_and_eval(cyvar.cname)
- if not value.is_optimized_out:
- 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):
local_cython_vars = self.get_cython_function().locals
max_name_length = len(max(local_cython_vars, key=len))
for name, cyvar in sorted(local_cython_vars.iteritems(), key=sortkey):
- self._print_if_initialized(cyvar, max_name_length)
+ if self.is_initialized(self.get_cython_function(), cyvar.name):
+ value = gdb.parse_and_eval(cyvar.cname)
+ if not value.is_optimized_out:
+ self.print_gdb_value(cyvar.name, value,
+ max_name_length, '')
class CyGlobals(CyLocals):
print 'C globals:'
for name, cyvar in sorted(module_globals.iteritems(), key=sortkey):
if name not in seen:
- self._print_if_initialized(cyvar, max_name_length,
- prefix=' ')
+ try:
+ value = gdb.parse_and_eval(cyvar.cname)
+ except RuntimeError:
+ pass
+ else:
+ if not value.is_optimized_out:
+ self.print_gdb_value(cyvar.name, value,
+ max_name_length, ' ')
class CyExec(CythonCommand, libpython.PyExec):
try:
cname = super(CyCValue, self).invoke(cyname, frame=frame)
return gdb.parse_and_eval(cname)
- except (gdb.GdbError, RuntimeError):
+ except (gdb.GdbError, RuntimeError), e:
# variable exists but may not have been initialized yet, or may be
# in the globals dict of the Cython module
d = self.get_cython_globals_dict()
if cyname in d:
return d[cyname]._gdbval
- raise gdb.GdbError("Variable %s not initialized yet." % cyname)
+ raise gdb.GdbError(str(e))
class CyLine(gdb.Function, CythonBase):
#print 'tp_flags = 0x%08x' % tp_flags
#print 'tp_name = %r' % tp_name
-
+
name_map = {'bool': PyBoolObjectPtr,
'classobj': PyClassObjectPtr,
'instance': PyInstanceObjectPtr,
if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
return PyTupleObjectPtr
if tp_flags & Py_TPFLAGS_STRING_SUBCLASS:
- return PyStringObjectPtr
+ try:
+ gdb.lookup_type('PyBytesObject')
+ return PyBytesObject
+ except RuntimeError:
+ return PyStringObjectPtr
if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
return PyUnicodeObjectPtr
if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
p = PyObjectPtr(gdbval)
cls = cls.subclass_from_type(p.type())
return cls(gdbval, cast_to=cls.get_gdb_type())
- except RuntimeError:
+ except RuntimeError, exc:
# Handle any kind of error e.g. NULL ptrs by simply using the base
# class
pass
out.write(self.safe_tp_name())
self.write_field_repr('args', out, visited)
-class PyBoolObjectPtr(PyObjectPtr):
- """
- Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
- <bool> instances (Py_True/Py_False) within the process being debugged.
- """
- _typename = 'PyBoolObject'
-
- def proxyval(self, visited):
- if int_from_int(self.field('ob_ival')):
- return True
- else:
- return False
-
class PyClassObjectPtr(PyObjectPtr):
"""
Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
<bool> instances (Py_True/Py_False) within the process being debugged.
"""
+
def proxyval(self, visited):
- if PyLongObjectPtr.proxyval(self, visited):
- return True
- else:
- return False
+ return bool(PyLongObjectPtr.proxyval(self, visited))
+
class PyNoneStructPtr(PyObjectPtr):
"""
out.write(byte)
out.write(quote)
+class PyStringObjectPtr(PyBytesObjectPtr):
+ _typename = 'PyStringObject'
+
+
class PyTupleObjectPtr(PyObjectPtr):
_typename = 'PyTupleObject'
pyframe = frame.get_pyop()
if pyframe is None:
return None
- val = str(getattr(pyframe, attr)); print val, val.proxyval(set()); return val
+
+ return str(getattr(pyframe, attr))
return None
context.
"""
- def stopped(self):
- return get_selected_inferior().pid == 0
+ def stopped(self, result):
+ match = re.search('^Program received signal .*', result, re.MULTILINE)
+ if match:
+ return match.group(0)
+ elif get_selected_inferior().pid == 0:
+ return result
+ else:
+ return None
def _stackdepth(self, frame):
depth = 0
of source code or the result of the last executed gdb command (passed
in as the `result` argument).
"""
- if self.stopped():
+ result = self.stopped(result)
+ if result:
print result.strip()
+ # check whether the program was killed by a signal, it should still
+ # have a stack.
+ try:
+ frame = gdb.selected_frame()
+ except RuntimeError:
+ pass
+ else:
+ print self.get_source_line(frame)
else:
frame = gdb.selected_frame()
output = None
hitbp = re.search(r'Breakpoint (\d+)', result)
is_relavant = self.is_relevant_function(frame)
- if hitbp or is_relavant or self.stopped():
+ if hitbp or is_relavant or self.stopped(result):
break
self.finish_executing(result)
else:
result = self._finish()
- if self.stopped():
+ if self.stopped(result):
break
newframe = gdb.selected_frame()