3044e5e2a762afd083a07a930822ad2194915c5d
[openbsd] /
1 """Test that lldb functions correctly after the inferior has crashed while in a recursive routine."""
2
3
4
5 import lldb
6 from lldbsuite.test.decorators import *
7 from lldbsuite.test.lldbtest import *
8 from lldbsuite.test import lldbplatformutil
9 from lldbsuite.test import lldbutil
10
11
12 class CrashingRecursiveInferiorTestCase(TestBase):
13
14     mydir = TestBase.compute_mydir(__file__)
15
16     @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
17     @expectedFailureNetBSD
18     def test_recursive_inferior_crashing(self):
19         """Test that lldb reliably catches the inferior crashing (command)."""
20         self.build()
21         self.recursive_inferior_crashing()
22
23     @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
24     def test_recursive_inferior_crashing_register(self):
25         """Test that lldb reliably reads registers from the inferior after crashing (command)."""
26         self.build()
27         self.recursive_inferior_crashing_registers()
28
29     @add_test_categories(['pyapi'])
30     def test_recursive_inferior_crashing_python(self):
31         """Test that lldb reliably catches the inferior crashing (Python API)."""
32         self.build()
33         self.recursive_inferior_crashing_python()
34
35     def test_recursive_inferior_crashing_expr(self):
36         """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""
37         self.build()
38         self.recursive_inferior_crashing_expr()
39
40     def set_breakpoint(self, line):
41         lldbutil.run_break_set_by_file_and_line(
42             self, "main.c", line, num_expected_locations=1, loc_exact=True)
43
44     def check_stop_reason(self):
45         # We should have one crashing thread
46         self.assertEqual(
47             len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())),
48             1,
49             STOPPED_DUE_TO_EXC_BAD_ACCESS)
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 recursive_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
64         # The exact stop reason depends on the platform
65         if self.platformIsDarwin():
66             stop_reason = 'stop reason = EXC_BAD_ACCESS'
67         elif self.getPlatform() == "linux" or self.getPlatform() == "freebsd":
68             stop_reason = 'stop reason = signal SIGSEGV'
69         else:
70             stop_reason = 'stop reason = invalid address'
71         self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
72                     substrs=['stopped',
73                              stop_reason])
74
75         # And it should report a backtrace that includes main and the crash
76         # site.
77         self.expect(
78             "thread backtrace all",
79             substrs=[
80                 stop_reason,
81                 'main',
82                 'argc',
83                 'argv',
84                 'recursive_function'])
85
86         # And it should report the correct line number.
87         self.expect("thread backtrace all",
88                     substrs=[stop_reason,
89                              'main.c:%d' % self.line])
90
91     def recursive_inferior_crashing_python(self):
92         """Inferior crashes upon launching; lldb should catch the event and stop."""
93         exe = self.getBuildArtifact("a.out")
94
95         target = self.dbg.CreateTarget(exe)
96         self.assertTrue(target, VALID_TARGET)
97
98         # Now launch the process, and do not stop at entry point.
99         # Both argv and envp are null.
100         process = target.LaunchSimple(
101             None, None, self.get_process_working_directory())
102
103         if process.GetState() != lldb.eStateStopped:
104             self.fail("Process should be in the 'stopped' state, "
105                       "instead the actual state is: '%s'" %
106                       lldbutil.state_type_to_str(process.GetState()))
107
108         threads = lldbutil.get_crashed_threads(self, process)
109         self.assertEqual(
110             len(threads),
111             1,
112             "Failed to stop the thread upon bad access exception")
113
114         if self.TraceOn():
115             lldbutil.print_stacktrace(threads[0])
116
117     def recursive_inferior_crashing_registers(self):
118         """Test that lldb can read registers 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         # lldb should be able to read from registers from the inferior after
126         # crashing.
127         lldbplatformutil.check_first_register_readable(self)
128
129     def recursive_inferior_crashing_expr(self):
130         """Test that the lldb expression interpreter can read symbols after crashing."""
131         exe = self.getBuildArtifact("a.out")
132         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
133
134         self.runCmd("run", RUN_SUCCEEDED)
135         self.check_stop_reason()
136
137         # The lldb expression interpreter should be able to read from addresses
138         # of the inferior after a crash.
139         self.expect("p i",
140                     startstr='(int) $0 =')
141