TestInferiorCrashing.py revision 92e33e925aeae87b3f91d8ec6ca585a6d9e13bfb
1"""Test that lldb functions correctly after the inferior has crashed.""" 2 3import os, time 4import unittest2 5import lldb, lldbutil 6from lldbtest import * 7 8class CrashingInferiorTestCase(TestBase): 9 10 mydir = os.path.join("functionalities", "inferior-crashing") 11 12 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 13 def test_inferior_crashing_dsym(self): 14 """Test that lldb reliably catches the inferior crashing (command).""" 15 self.buildDsym() 16 self.inferior_crashing() 17 18 def test_inferior_crashing_dwarf(self): 19 """Test that lldb reliably catches the inferior crashing (command).""" 20 self.buildDwarf() 21 self.inferior_crashing() 22 23 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 24 def test_inferior_crashing_registers_dsym(self): 25 """Test that lldb reliably reads registers from the inferior after crashing (command).""" 26 self.buildDsym() 27 self.inferior_crashing_registers() 28 29 def test_inferior_crashing_register_dwarf(self): 30 """Test that lldb reliably reads registers from the inferior after crashing (command).""" 31 self.buildDwarf() 32 self.inferior_crashing_registers() 33 34 @python_api_test 35 def test_inferior_crashing_python(self): 36 """Test that lldb reliably catches the inferior crashing (Python API).""" 37 self.buildDefault() 38 self.inferior_crashing_python() 39 40 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 41 def test_inferior_crashing_expr(self): 42 """Test that the lldb expression interpreter can read from the inferior after crashing (command).""" 43 self.buildDsym() 44 self.inferior_crashing_expr() 45 46 # bugzilla 15784 - the same commands fail when run on Linux from the lldb command line 47 def test_inferior_crashing_expr(self): 48 """Test that the lldb expression interpreter can read from the inferior after crashing (command).""" 49 self.buildDwarf() 50 self.inferior_crashing_expr() 51 52 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 53 def test_inferior_crashing_step(self): 54 """Test that lldb functions correctly after stepping through a crash.""" 55 self.buildDsym() 56 self.inferior_crashing_step() 57 58 # bugzilla 15784 - the same commands fail when run on Linux from the lldb command line 59 def test_inferior_crashing_step(self): 60 """Test that lldb functions correctly after stepping through a crash.""" 61 self.buildDwarf() 62 self.inferior_crashing_step() 63 64 def set_breakpoint(self, line): 65 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True) 66 67 def setUp(self): 68 # Call super's setUp(). 69 TestBase.setUp(self) 70 # Find the line number of the crash. 71 self.line = line_number('main.c', '// Crash here.') 72 73 def inferior_crashing(self): 74 """Inferior crashes upon launching; lldb should catch the event and stop.""" 75 exe = os.path.join(os.getcwd(), "a.out") 76 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 77 78 self.runCmd("run", RUN_SUCCEEDED) 79 80 if sys.platform.startswith("darwin"): 81 stop_reason = 'stop reason = EXC_BAD_ACCESS' 82 else: 83 stop_reason = 'stop reason = invalid address' 84 85 # The stop reason of the thread should be a bad access exception. 86 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 87 substrs = ['stopped', 88 stop_reason]) 89 90 # And it should report the correct line number. 91 self.expect("thread backtrace all", 92 substrs = [stop_reason, 93 'main.c:%d' % self.line]) 94 95 def inferior_crashing_python(self): 96 """Inferior crashes upon launching; lldb should catch the event and stop.""" 97 exe = os.path.join(os.getcwd(), "a.out") 98 99 target = self.dbg.CreateTarget(exe) 100 self.assertTrue(target, VALID_TARGET) 101 102 # Now launch the process, and do not stop at entry point. 103 # Both argv and envp are null. 104 process = target.LaunchSimple(None, None, os.getcwd()) 105 106 import lldbutil 107 if process.GetState() != lldb.eStateStopped: 108 self.fail("Process should be in the 'stopped' state, " 109 "instead the actual state is: '%s'" % 110 lldbutil.state_type_to_str(process.GetState())) 111 112 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonException) 113 if not thread: 114 self.fail("Fail to stop the thread upon bad access exception") 115 116 if self.TraceOn(): 117 lldbutil.print_stacktrace(thread) 118 119 def inferior_crashing_registers(self): 120 """Test that lldb can read registers after crashing.""" 121 exe = os.path.join(os.getcwd(), "a.out") 122 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 123 124 self.runCmd("run", RUN_SUCCEEDED) 125 126 if sys.platform.startswith("darwin"): 127 stop_reason = 'stop reason = EXC_BAD_ACCESS' 128 else: 129 stop_reason = 'stop reason = invalid address' 130 131 # lldb should be able to read from registers from the inferior after crashing. 132 self.expect("register read eax", 133 substrs = ['eax = 0x']) 134 135 def inferior_crashing_expr(self): 136 """Test that the lldb expression interpreter can read symbols after crashing.""" 137 exe = os.path.join(os.getcwd(), "a.out") 138 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 139 140 self.runCmd("run", RUN_SUCCEEDED) 141 142 if sys.platform.startswith("darwin"): 143 stop_reason = 'stop reason = EXC_BAD_ACCESS' 144 else: 145 stop_reason = 'stop reason = invalid address' 146 147 # The stop reason of the thread should be a bad access exception. 148 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 149 substrs = ['stopped', stop_reason]) 150 151 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 152 self.expect("p argc", 153 startstr = '(int) $0 = 1') 154 155 self.expect("p hello_world", 156 substrs = ['Hello']) 157 158 def inferior_crashing_step(self): 159 """Test that lldb functions correctly after stepping through a crash.""" 160 exe = os.path.join(os.getcwd(), "a.out") 161 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 162 163 self.set_breakpoint(self.line) 164 self.runCmd("run", RUN_SUCCEEDED) 165 166 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 167 substrs = ['main.c:%d' % self.line, 168 'stop reason = breakpoint']) 169 170 self.runCmd("next") 171 172 if sys.platform.startswith("darwin"): 173 stop_reason = 'stop reason = EXC_BAD_ACCESS' 174 else: 175 stop_reason = 'stop reason = invalid address' 176 177 # The stop reason of the thread should be a bad access exception. 178 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 179 substrs = ['stopped', stop_reason]) 180 181 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 182 self.expect("p argv[0]", 183 substrs = ['a.out']) 184 self.expect("p null_ptr", 185 substrs = ['= 0x0']) 186 187 # lldb should be able to read from registers from the inferior after crashing. 188 self.expect("register read eax", 189 substrs = ['eax = 0x']) 190 191 # And it should report the correct line number. 192 self.expect("thread backtrace all", 193 substrs = [stop_reason, 194 'main.c:%d' % self.line]) 195 196if __name__ == '__main__': 197 import atexit 198 lldb.SBDebugger.Initialize() 199 atexit.register(lambda: lldb.SBDebugger.Terminate()) 200 unittest2.main() 201