Commit 476af996 authored by mark's avatar mark

Choose PyString/PyBytesObjectPtr according to python version + support signals...

Choose PyString/PyBytesObjectPtr according to python version + support signals terminating the inferior.
parent 7c6598c1
......@@ -70,6 +70,8 @@ class DebugTestCase(unittest.TestCase):
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()
......@@ -140,6 +142,13 @@ class TestBreak(DebugTestCase):
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):
......@@ -291,6 +300,7 @@ def _main():
"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)
......@@ -311,4 +321,6 @@ def main(trace_code=False):
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
......@@ -390,8 +390,9 @@ class CythonBase(object):
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):
......@@ -1077,18 +1078,16 @@ class CyLocals(CythonCommand):
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):
......@@ -1124,8 +1123,14 @@ 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):
......@@ -1284,14 +1289,14 @@ class CyCValue(CyCName):
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):
......
......@@ -332,7 +332,7 @@ class PyObjectPtr(object):
#print 'tp_flags = 0x%08x' % tp_flags
#print 'tp_name = %r' % tp_name
name_map = {'bool': PyBoolObjectPtr,
'classobj': PyClassObjectPtr,
'instance': PyInstanceObjectPtr,
......@@ -357,7 +357,11 @@ class PyObjectPtr(object):
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:
......@@ -380,7 +384,7 @@ class PyObjectPtr(object):
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
......@@ -555,19 +559,6 @@ class PyBaseExceptionObjectPtr(PyObjectPtr):
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):
"""
......@@ -821,11 +812,10 @@ class PyBoolObjectPtr(PyLongObjectPtr):
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):
"""
......@@ -1073,6 +1063,10 @@ class PyBytesObjectPtr(PyObjectPtr):
out.write(byte)
out.write(quote)
class PyStringObjectPtr(PyBytesObjectPtr):
_typename = 'PyStringObject'
class PyTupleObjectPtr(PyObjectPtr):
_typename = 'PyTupleObject'
......@@ -1691,7 +1685,8 @@ class PyNameEquals(gdb.Function):
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
......@@ -1924,8 +1919,14 @@ class GenericCodeStepper(gdb.Command):
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
......@@ -1941,8 +1942,17 @@ class GenericCodeStepper(gdb.Command):
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
......@@ -1985,7 +1995,7 @@ class GenericCodeStepper(gdb.Command):
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)
......@@ -2012,7 +2022,7 @@ class GenericCodeStepper(gdb.Command):
else:
result = self._finish()
if self.stopped():
if self.stopped(result):
break
newframe = gdb.selected_frame()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment