TestInferiorCrashing.py revision 6bc4dcdfbcdfa455299d2123011b82a77351ee72
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_dsym(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 def test_inferior_crashing_expr_dwarf(self): 47 """Test that the lldb expression interpreter can read from the inferior after crashing (command).""" 48 self.buildDwarf() 49 self.inferior_crashing_expr() 50 51 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 52 def test_inferior_crashing_step_dsym(self): 53 """Test that lldb functions correctly after stepping through a crash.""" 54 self.buildDsym() 55 self.inferior_crashing_step() 56 57 def test_inferior_crashing_step_dwarf(self): 58 """Test that stepping after a crash behaves correctly.""" 59 self.buildDwarf() 60 self.inferior_crashing_step() 61 62 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 63 def test_inferior_crashing_step_after_break_dsym(self): 64 """Test that stepping after a crash behaves correctly.""" 65 self.buildDsym() 66 self.inferior_crashing_step_after_break() 67 68 @expectedFailureLinux # due to llvm.org/pr15988 -- step over misbehaves after crash 69 def test_inferior_crashing_step_after_break_dwarf(self): 70 """Test that lldb functions correctly after stepping through a crash.""" 71 self.buildDwarf() 72 self.inferior_crashing_step_after_break() 73 74 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 75 def test_inferior_crashing_expr_step_and_expr_dsym(self): 76 """Test that lldb expressions work before and after stepping after a crash.""" 77 self.buildDsym() 78 self.inferior_crashing_expr_step_expr() 79 80 @expectedFailureLinux # due to llvm.org/pr15989 -- expression fails after crash and step 81 def test_inferior_crashing_expr_step_and_expr_dwarf(self): 82 """Test that lldb expressions work before and after stepping after a crash.""" 83 self.buildDwarf() 84 self.inferior_crashing_expr_step_expr() 85 86 def set_breakpoint(self, line): 87 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True) 88 89 def setUp(self): 90 # Call super's setUp(). 91 TestBase.setUp(self) 92 # Find the line number of the crash. 93 self.line = line_number('main.c', '// Crash here.') 94 95 def inferior_crashing(self): 96 """Inferior crashes upon launching; lldb should catch the event and stop.""" 97 exe = os.path.join(os.getcwd(), "a.out") 98 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 99 100 self.runCmd("run", RUN_SUCCEEDED) 101 102 if sys.platform.startswith("darwin"): 103 stop_reason = 'stop reason = EXC_BAD_ACCESS' 104 else: 105 stop_reason = 'stop reason = invalid address' 106 107 # The stop reason of the thread should be a bad access exception. 108 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 109 substrs = ['stopped', 110 stop_reason]) 111 112 # And it should report the correct line number. 113 self.expect("thread backtrace all", 114 substrs = [stop_reason, 115 'main.c:%d' % self.line]) 116 117 def inferior_crashing_python(self): 118 """Inferior crashes upon launching; lldb should catch the event and stop.""" 119 exe = os.path.join(os.getcwd(), "a.out") 120 121 target = self.dbg.CreateTarget(exe) 122 self.assertTrue(target, VALID_TARGET) 123 124 # Now launch the process, and do not stop at entry point. 125 # Both argv and envp are null. 126 process = target.LaunchSimple(None, None, os.getcwd()) 127 128 import lldbutil 129 if process.GetState() != lldb.eStateStopped: 130 self.fail("Process should be in the 'stopped' state, " 131 "instead the actual state is: '%s'" % 132 lldbutil.state_type_to_str(process.GetState())) 133 134 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonException) 135 if not thread: 136 self.fail("Fail to stop the thread upon bad access exception") 137 138 if self.TraceOn(): 139 lldbutil.print_stacktrace(thread) 140 141 def inferior_crashing_registers(self): 142 """Test that lldb can read registers after crashing.""" 143 exe = os.path.join(os.getcwd(), "a.out") 144 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 145 146 self.runCmd("run", RUN_SUCCEEDED) 147 148 if sys.platform.startswith("darwin"): 149 stop_reason = 'stop reason = EXC_BAD_ACCESS' 150 else: 151 stop_reason = 'stop reason = invalid address' 152 153 # lldb should be able to read from registers from the inferior after crashing. 154 self.expect("register read eax", 155 substrs = ['eax = 0x']) 156 157 def inferior_crashing_expr(self): 158 """Test that the lldb expression interpreter can read symbols after crashing.""" 159 exe = os.path.join(os.getcwd(), "a.out") 160 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 161 162 self.runCmd("run", RUN_SUCCEEDED) 163 164 if sys.platform.startswith("darwin"): 165 stop_reason = 'stop reason = EXC_BAD_ACCESS' 166 else: 167 stop_reason = 'stop reason = invalid address' 168 169 # The stop reason of the thread should be a bad access exception. 170 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 171 substrs = ['stopped', stop_reason]) 172 173 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 174 self.expect("p argc", 175 startstr = '(int) $0 = 1') 176 177 self.expect("p hello_world", 178 substrs = ['Hello']) 179 180 def inferior_crashing_step(self): 181 """Test that lldb functions correctly after stepping through a crash.""" 182 exe = os.path.join(os.getcwd(), "a.out") 183 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 184 185 self.set_breakpoint(self.line) 186 self.runCmd("run", RUN_SUCCEEDED) 187 188 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 189 substrs = ['main.c:%d' % self.line, 190 'stop reason = breakpoint']) 191 192 self.runCmd("next") 193 194 if sys.platform.startswith("darwin"): 195 stop_reason = 'stop reason = EXC_BAD_ACCESS' 196 else: 197 stop_reason = 'stop reason = invalid address' 198 199 # The stop reason of the thread should be a bad access exception. 200 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 201 substrs = ['stopped', stop_reason]) 202 203 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 204 self.expect("p argv[0]", 205 substrs = ['a.out']) 206 self.expect("p null_ptr", 207 substrs = ['= 0x0']) 208 209 # lldb should be able to read from registers from the inferior after crashing. 210 self.expect("register read eax", 211 substrs = ['eax = 0x']) 212 213 # And it should report the correct line number. 214 self.expect("thread backtrace all", 215 substrs = [stop_reason, 216 'main.c:%d' % self.line]) 217 218 def inferior_crashing_step_after_break(self): 219 """Test that lldb behaves correctly when stepping after a crash.""" 220 exe = os.path.join(os.getcwd(), "a.out") 221 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 222 223 self.runCmd("run", RUN_SUCCEEDED) 224 225 if sys.platform.startswith("darwin"): 226 stop_reason = 'stop reason = EXC_BAD_ACCESS' 227 else: 228 stop_reason = 'stop reason = invalid address' 229 230 self.runCmd("next") 231 232 # The stop reason of the thread should still be a bad access exception. 233 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 234 substrs = ['stopped', stop_reason]) 235 236 def inferior_crashing_expr_step_expr(self): 237 """Test that lldb expressions work before and after stepping after a crash.""" 238 exe = os.path.join(os.getcwd(), "a.out") 239 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 240 241 self.runCmd("run", RUN_SUCCEEDED) 242 243 if sys.platform.startswith("darwin"): 244 stop_reason = 'stop reason = EXC_BAD_ACCESS' 245 else: 246 stop_reason = 'stop reason = invalid address' 247 248 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 249 self.expect("p argv[0]", 250 substrs = ['a.out']) 251 252 self.runCmd("next") 253 254 if sys.platform.startswith("darwin"): 255 stop_reason = 'stop reason = EXC_BAD_ACCESS' 256 else: 257 stop_reason = 'stop reason = invalid address' 258 259 # The lldb expression interpreter should be able to read from addresses of the inferior after a crash. 260 self.expect("p argv[0]", 261 substrs = ['a.out']) 262 263 264if __name__ == '__main__': 265 import atexit 266 lldb.SBDebugger.Initialize() 267 atexit.register(lambda: lldb.SBDebugger.Terminate()) 268 unittest2.main() 269