1 """Test that lldb steps correctly after the inferior has crashed while in a recursive routine."""
5 from lldbsuite.test.decorators import *
6 from lldbsuite.test.lldbtest import *
7 from lldbsuite.test import lldbplatformutil
8 from lldbsuite.test import lldbutil
11 class CrashingRecursiveInferiorStepTestCase(TestBase):
13 mydir = TestBase.compute_mydir(__file__)
15 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
16 def test_recursive_inferior_crashing_step(self):
17 """Test that stepping after a crash behaves correctly."""
19 self.recursive_inferior_crashing_step()
21 @skipIfTargetAndroid() # debuggerd interferes with this test on Android
22 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
23 def test_recursive_inferior_crashing_step_after_break(self):
24 """Test that lldb functions correctly after stepping through a crash."""
26 self.recursive_inferior_crashing_step_after_break()
28 # Inferior exits after stepping after a segfault. This is working as
32 @expectedFailureNetBSD
33 def test_recursive_inferior_crashing_expr_step_and_expr(self):
34 """Test that lldb expressions work before and after stepping after a crash."""
36 self.recursive_inferior_crashing_expr_step_expr()
38 def set_breakpoint(self, line):
39 lldbutil.run_break_set_by_file_and_line(
40 self, "main.c", line, num_expected_locations=1, loc_exact=True)
42 def check_stop_reason(self):
43 # We should have one crashing thread
46 lldbutil.get_crashed_threads(
48 self.dbg.GetSelectedTarget().GetProcess())), 1,
49 STOPPED_DUE_TO_EXC_BAD_ACCESS)
52 # Call super's setUp().
54 # Find the line number of the crash.
55 self.line = line_number('main.c', '// Crash here.')
57 def recursive_inferior_crashing_step(self):
58 """Test that lldb functions correctly after stepping through a crash."""
59 exe = self.getBuildArtifact("a.out")
60 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
62 self.set_breakpoint(self.line)
63 self.runCmd("run", RUN_SUCCEEDED)
67 STOPPED_DUE_TO_BREAKPOINT,
68 substrs=['main.c:%d' % self.line, 'stop reason = breakpoint'])
71 self.check_stop_reason()
73 # The lldb expression interpreter should be able to read from addresses
74 # of the inferior after a crash.
75 self.expect("p i", substrs=['(int) $0 ='])
77 # lldb should be able to read from registers from the inferior after
79 lldbplatformutil.check_first_register_readable(self)
81 # And it should report the correct line number.
82 self.expect("thread backtrace all", substrs=['main.c:%d' % self.line])
84 def recursive_inferior_crashing_step_after_break(self):
85 """Test that lldb behaves correctly when stepping after a crash."""
86 exe = self.getBuildArtifact("a.out")
87 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
89 self.runCmd("run", RUN_SUCCEEDED)
90 self.check_stop_reason()
92 expected_state = 'exited' # Provide the exit code.
93 if self.platformIsDarwin():
94 # TODO: Determine why 'next' and 'continue' have no effect after a
96 expected_state = 'stopped'
98 self.expect("next", substrs=['Process', expected_state])
100 if expected_state == 'exited':
104 substrs=['Process must be launched'])
106 self.check_stop_reason()
108 def recursive_inferior_crashing_expr_step_expr(self):
109 """Test that lldb expressions work before and after stepping after a crash."""
110 exe = self.getBuildArtifact("a.out")
111 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
113 self.runCmd("run", RUN_SUCCEEDED)
114 self.check_stop_reason()
116 # The lldb expression interpreter should be able to read from addresses
117 # of the inferior after a crash.
118 self.expect("p null", startstr='(char *) $0 = 0x0')
122 # The lldb expression interpreter should be able to read from addresses
123 # of the inferior after a step.
124 self.expect("p null", startstr='(char *) $1 = 0x0')
126 self.check_stop_reason()