1"""Test that lldb functions correctly after the inferior has crashed.""" 2 3 4 5import lldb 6from lldbsuite.test import lldbutil 7from lldbsuite.test import lldbplatformutil 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10 11 12class CrashingInferiorTestCase(TestBase): 13 14 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") 15 @expectedFailureNetBSD 16 def test_inferior_crashing(self): 17 """Test that lldb reliably catches the inferior crashing (command).""" 18 self.build() 19 self.inferior_crashing() 20 21 def test_inferior_crashing_register(self): 22 """Test that lldb reliably reads registers from the inferior after crashing (command).""" 23 self.build() 24 self.inferior_crashing_registers() 25 26 @add_test_categories(['pyapi']) 27 def test_inferior_crashing_python(self): 28 """Test that lldb reliably catches the inferior crashing (Python API).""" 29 self.build() 30 self.inferior_crashing_python() 31 32 def test_inferior_crashing_expr(self): 33 """Test that the lldb expression interpreter can read from the inferior after crashing (command).""" 34 self.build() 35 self.inferior_crashing_expr() 36 37 def set_breakpoint(self, line): 38 lldbutil.run_break_set_by_file_and_line( 39 self, "main.c", line, num_expected_locations=1, loc_exact=True) 40 41 def check_stop_reason(self): 42 # We should have one crashing thread 43 self.assertEqual( 44 len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())), 45 1, 46 STOPPED_DUE_TO_EXC_BAD_ACCESS) 47 48 def get_api_stop_reason(self): 49 return lldb.eStopReasonException 50 51 def setUp(self): 52 # Call super's setUp(). 53 TestBase.setUp(self) 54 # Find the line number of the crash. 55 self.line = line_number('main.c', '// Crash here.') 56 57 def inferior_crashing(self): 58 """Inferior crashes upon launching; lldb should catch the event and stop.""" 59 exe = self.getBuildArtifact("a.out") 60 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 61 62 self.runCmd("run", RUN_SUCCEEDED) 63 # The exact stop reason depends on the platform 64 if self.platformIsDarwin(): 65 stop_reason = 'stop reason = EXC_BAD_ACCESS' 66 elif self.getPlatform() == "linux" or self.getPlatform() == "freebsd": 67 stop_reason = 'stop reason = signal SIGSEGV' 68 else: 69 stop_reason = 'stop reason = invalid address' 70 self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS, 71 substrs=['stopped', 72 stop_reason]) 73 74 # And it should report the correct line number. 75 self.expect("thread backtrace all", 76 substrs=[stop_reason, 77 'main.c:%d' % self.line]) 78 79 def inferior_crashing_python(self): 80 """Inferior crashes upon launching; lldb should catch the event and stop.""" 81 exe = self.getBuildArtifact("a.out") 82 83 target = self.dbg.CreateTarget(exe) 84 self.assertTrue(target, VALID_TARGET) 85 86 # Now launch the process, and do not stop at entry point. 87 # Both argv and envp are null. 88 process = target.LaunchSimple( 89 None, None, self.get_process_working_directory()) 90 91 if process.GetState() != lldb.eStateStopped: 92 self.fail("Process should be in the 'stopped' state, " 93 "instead the actual state is: '%s'" % 94 lldbutil.state_type_to_str(process.GetState())) 95 96 threads = lldbutil.get_crashed_threads(self, process) 97 self.assertEqual( 98 len(threads), 99 1, 100 "Failed to stop the thread upon bad access exception") 101 102 if self.TraceOn(): 103 lldbutil.print_stacktrace(threads[0]) 104 105 def inferior_crashing_registers(self): 106 """Test that lldb can read registers after crashing.""" 107 exe = self.getBuildArtifact("a.out") 108 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 109 110 self.runCmd("run", RUN_SUCCEEDED) 111 self.check_stop_reason() 112 113 # lldb should be able to read from registers from the inferior after 114 # crashing. 115 lldbplatformutil.check_first_register_readable(self) 116 117 def inferior_crashing_expr(self): 118 """Test that the lldb expression interpreter can read symbols after crashing.""" 119 exe = self.getBuildArtifact("a.out") 120 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 121 122 self.runCmd("run", RUN_SUCCEEDED) 123 self.check_stop_reason() 124 125 # The lldb expression interpreter should be able to read from addresses 126 # of the inferior after a crash. 127 self.expect("p argc", 128 startstr='(int) $0 = 1') 129 130 self.expect("p hello_world", 131 substrs=['Hello']) 132