summaryrefslogtreecommitdiffstats
path: root/test_gdb.py
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2010-02-27 00:40:21 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2010-02-27 00:40:21 -0500
commit150a0120ecbbf16091ddcbe1d0bd752619abc352 (patch)
treec0aff7b3b083ccea31fb7e2a02485fb0381732cb /test_gdb.py
parent64296d87c8db921ec58528d5a460a1f1ded1219c (diff)
downloadlibpython-150a0120ecbbf16091ddcbe1d0bd752619abc352.zip
libpython-150a0120ecbbf16091ddcbe1d0bd752619abc352.tar.gz
libpython-150a0120ecbbf16091ddcbe1d0bd752619abc352.tar.xz
Improve layout
Diffstat (limited to 'test_gdb.py')
-rw-r--r--test_gdb.py83
1 files changed, 47 insertions, 36 deletions
diff --git a/test_gdb.py b/test_gdb.py
index e9ce82a..d7cd237 100644
--- a/test_gdb.py
+++ b/test_gdb.py
@@ -20,23 +20,26 @@ except OSError:
raise TestSkipped("Couldn't find gdb on the path")
gdb_version_number = re.search(r"^GNU gdb [^\d]*(\d+)\.", gdb_version)
if int(gdb_version_number.group(1)) < 7:
- raise TestSkipped("gdb versions before 7.0 didn't support python embedding."
+ raise TestSkipped("gdb versions before 7.0 didn't support python embedding"
" Saw:\n" + gdb_version)
# Verify that "gdb" was built with the embedded python support enabled:
-p = subprocess.Popen(["gdb", "--batch",
- "--eval-command=python import sys; print sys.version_info"],
+cmd = "--eval-command=python import sys; print sys.version_info"
+p = subprocess.Popen(["gdb", "--batch", cmd],
stdout=subprocess.PIPE)
gdbpy_version, _ = p.communicate()
if gdbpy_version == '':
raise TestSkipped("gdb not built with embedded python support")
+
class DebuggerTests(unittest.TestCase):
"""Test that the debugger can debug Python."""
def run_gdb(self, *args):
- """Runs gdb with the command line given by *args. Returns its stdout, stderr
+ """Runs gdb with the command line given by *args.
+
+ Returns its stdout, stderr
"""
out, err = subprocess.Popen(
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
@@ -106,8 +109,10 @@ class DebuggerTests(unittest.TestCase):
#
# For a nested structure, the first time we hit the breakpoint will
# give us the top-level structure
- gdb_output = self.get_stack_trace(source, 'PyObject_Print', commands_after_breakpoint)
- m = re.match('.*#0 PyObject_Print \(op\=(.*?), fp=.*\).*', gdb_output, re.DOTALL)
+ gdb_output = self.get_stack_trace(source, 'PyObject_Print',
+ commands_after_breakpoint)
+ m = re.match('.*#0 PyObject_Print \(op\=(.*?), fp=.*\).*',
+ gdb_output, re.DOTALL)
#print m.groups()
return m.group(1), gdb_output
@@ -118,9 +123,10 @@ class DebuggerTests(unittest.TestCase):
def assertGdbRepr(self, val, commands_after_breakpoint=None):
# Ensure that gdb's rendering of the value in a debugged process
# matches repr(value) in this process:
- gdb_repr, gdb_output = self.get_gdb_repr('print ' + repr(val), commands_after_breakpoint)
+ gdb_repr, gdb_output = self.get_gdb_repr('print ' + repr(val),
+ commands_after_breakpoint)
self.assertEquals(gdb_repr, repr(val), gdb_output)
-
+
def test_int(self):
self.assertGdbRepr(42)
self.assertGdbRepr(0)
@@ -141,7 +147,7 @@ class DebuggerTests(unittest.TestCase):
def test_dicts(self):
self.assertGdbRepr({})
- self.assertGdbRepr({'foo':'bar'})
+ self.assertGdbRepr({'foo': 'bar'})
def test_lists(self):
self.assertGdbRepr([])
@@ -152,20 +158,12 @@ class DebuggerTests(unittest.TestCase):
self.assertGdbRepr('And now for something hopefully the same')
def test_tuples(self):
- self.assertGdbRepr( tuple() )
- self.assertGdbRepr( (1,) )
+ self.assertGdbRepr(tuple())
+ self.assertGdbRepr((1,))
def test_unicode(self):
- self.assertGdbRepr( u'hello world', )
- self.assertGdbRepr( u'\u2620')
-
- def assert_is_failsafe_repr(self, gdb_repr, exp_type='unknown'):
- '''Verify that the given gdb_repr string is the expected failsafe
- representation for when there's corrupt data within the inferior
- process'''
- self.assertTrue(re.match('<%s at remote 0x[0-9a-f]+>' % exp_type,
- gdb_repr),
- 'Unexpected gdb representation: %r' % gdb_repr)
+ self.assertGdbRepr(u'hello world')
+ self.assertGdbRepr(u'\u2620')
def test_classic_class(self):
gdb_repr, gdb_output = self.get_gdb_repr('''
@@ -174,34 +172,47 @@ class Foo:
foo = Foo();
foo.an_int = 42;
print foo''')
- # FIXME: is there an "assertMatches"; should there be?
+ # FIXME: is there an "assertMatches"; should there be?
m = re.match(r'<Foo\(an_int=42\) at remote 0x[0-9a-f]+>', gdb_repr)
- self.assertTrue(m, msg='Unexpected classic-class rendering %r' % gdb_repr)
+ self.assertTrue(m,
+ msg='Unexpected classic-class rendering %r' % gdb_repr)
+
+ def assertSane(self, source, corruption, exp_type='unknown'):
+ '''Run Python under gdb, corrupting variables in the inferior process
+ immediately before taking a backtrace.
+
+ Verify that the variable's representation is the expected failsafe
+ representation'''
+ gdb_repr, gdb_output = \
+ self.get_gdb_repr(source,
+ commands_after_breakpoint=[corruption])
+ self.assertTrue(re.match('<%s at remote 0x[0-9a-f]+>' % exp_type,
+ gdb_repr),
+ 'Unexpected gdb representation: %r\n%s' % \
+ (gdb_repr, gdb_output))
def test_NULL_ob_type(self):
- gdb_repr, gdb_output = self.get_gdb_repr('print 42',
- commands_after_breakpoint=['set op->ob_type=0'])
- self.assert_is_failsafe_repr(gdb_repr)
+ self.assertSane('print 42',
+ 'set op->ob_type=0')
def test_corrupt_ob_type(self):
- gdb_repr, gdb_output = self.get_gdb_repr('print "this string will have its ob_type corrupted"',
- commands_after_breakpoint=['set op->ob_type=0xDEADBEEF'])
- self.assert_is_failsafe_repr(gdb_repr)
+ self.assertSane('print 42',
+ 'set op->ob_type=0xDEADBEEF')
def test_corrupt_tp_flags(self):
- gdb_repr, gdb_output = self.get_gdb_repr('print 42',
- commands_after_breakpoint=['set op->ob_type->tp_flags=0x0'])
- self.assert_is_failsafe_repr(gdb_repr, exp_type='int')
+ self.assertSane('print 42',
+ 'set op->ob_type->tp_flags=0x0',
+ exp_type='int')
def test_corrupt_tp_name(self):
- gdb_repr, gdb_output = self.get_gdb_repr('print 42',
- commands_after_breakpoint=['set op->ob_type->tp_name=0xDEADBEEF'])
- self.assert_is_failsafe_repr(gdb_repr)
-
+ self.assertSane('print 42',
+ 'set op->ob_type->tp_name=0xDEADBEEF')
+
# TODO:
# new-style classes
# frames
+
def test_main():
#run_unittest(DebuggerTests)
unittest.main()