Added an integration test to step through a crash and then test for globals, locals, arguments, registers and the back-trace.

llvm-svn: 181599
This commit is contained in:
Ashok Thirumurthi 2013-05-10 14:37:49 +00:00
parent 655d3fa3c1
commit f19caa1227
2 changed files with 69 additions and 6 deletions

View File

@ -2,7 +2,7 @@
import os, time import os, time
import unittest2 import unittest2
import lldb import lldb, lldbutil
from lldbtest import * from lldbtest import *
class CrashingInferiorTestCase(TestBase): class CrashingInferiorTestCase(TestBase):
@ -38,18 +38,34 @@ class CrashingInferiorTestCase(TestBase):
self.inferior_crashing_python() self.inferior_crashing_python()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@unittest2.expectedFailure # bugzilla 15784? @expectedFailureDarwin # bugzilla 15784
def test_inferior_crashing_expr(self): def test_inferior_crashing_expr(self):
"""Test that the lldb expression interpreter can read from the inferior after crashing (command).""" """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
self.buildDsym() self.buildDsym()
self.inferior_crashing_expr() self.inferior_crashing_expr()
@unittest2.expectedFailure # bugzilla 15784 @expectedFailureDarwin # bugzilla 15784
def test_inferior_crashing_expr(self): def test_inferior_crashing_expr(self):
"""Test that the lldb expression interpreter can read from the inferior after crashing (command).""" """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
self.buildDwarf() self.buildDwarf()
self.inferior_crashing_expr() self.inferior_crashing_expr()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@expectedFailureDarwin # bugzilla 15784
def test_inferior_crashing_step(self):
"""Test that lldb functions correctly after stepping through a crash."""
self.buildDsym()
self.inferior_crashing_step()
@expectedFailureDarwin # bugzilla 15784
def test_inferior_crashing_step(self):
"""Test that lldb functions correctly after stepping through a crash."""
self.buildDwarf()
self.inferior_crashing_step()
def set_breakpoint(self, line):
lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
def setUp(self): def setUp(self):
# Call super's setUp(). # Call super's setUp().
TestBase.setUp(self) TestBase.setUp(self)
@ -130,9 +146,54 @@ class CrashingInferiorTestCase(TestBase):
else: else:
stop_reason = 'stop reason = invalid address' stop_reason = 'stop reason = invalid address'
# The lldb expression interpreter should be able to read from addresses of the inferior during process exit. # The stop reason of the thread should be a bad access exception.
self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
substrs = ['stopped', stop_reason])
# The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
self.expect("p argc", self.expect("p argc",
startstr = ['(int) $0 = 1']) startstr = '(int) $0 = 1')
self.expect("p hello_world",
substrs = ['Hello'])
def inferior_crashing_step(self):
"""Test that lldb functions correctly after stepping through a crash."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
self.set_breakpoint(self.line)
self.runCmd("run", RUN_SUCCEEDED)
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['main.c:%d' % self.line,
'stop reason = breakpoint'])
self.runCmd("next")
if sys.platform.startswith("darwin"):
stop_reason = 'stop reason = EXC_BAD_ACCESS'
else:
stop_reason = 'stop reason = invalid address'
# The stop reason of the thread should be a bad access exception.
self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
substrs = ['stopped', stop_reason])
# The lldb expression interpreter should be able to read from addresses of the inferior after a crash.
self.expect("p argv[0]",
substrs = ['a.out'])
self.expect("p null_ptr",
substrs = ['= 0x0'])
# lldb should be able to read from registers from the inferior after crashing.
self.expect("register read eax",
substrs = ['eax = 0x'])
# And it should report the correct line number.
self.expect("thread backtrace all",
substrs = [stop_reason,
'main.c:%d' % self.line])
if __name__ == '__main__': if __name__ == '__main__':
import atexit import atexit

View File

@ -8,9 +8,11 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <stdio.h> #include <stdio.h>
const char *hello_world = "Hello, segfault!";
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
int *null_ptr = 0; int *null_ptr = 0;
printf("Hello, segfault!\n"); printf("%s\n", hello_world);
printf("Now crash %d\n", *null_ptr); // Crash here. printf("Now crash %d\n", *null_ptr); // Crash here.
} }