]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/functionalities/inferior-assert/TestInferiorAssert.py
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / functionalities / inferior-assert / TestInferiorAssert.py
1 """Test that lldb functions correctly after the inferior has asserted."""
2
3 from __future__ import print_function
4
5
6 import os
7 import time
8 import lldb
9 from lldbsuite.test import lldbutil
10 from lldbsuite.test import lldbplatformutil
11 from lldbsuite.test.decorators import *
12 from lldbsuite.test.lldbtest import *
13
14
15 class AssertingInferiorTestCase(TestBase):
16
17     mydir = TestBase.compute_mydir(__file__)
18
19     @expectedFailureAll(
20         oslist=["windows"],
21         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
22     @expectedFailureAll(
23         oslist=["linux"],
24         archs=["arm"],
25         bugnumber="llvm.org/pr25338")
26     @expectedFailureAll(bugnumber="llvm.org/pr26592", triple='^mips')
27     def test_inferior_asserting(self):
28         """Test that lldb reliably catches the inferior asserting (command)."""
29         self.build()
30         self.inferior_asserting()
31
32     @expectedFailureAll(
33         oslist=["windows"],
34         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
35     @expectedFailureAndroid(
36         api_levels=list(
37             range(
38                 16 +
39                 1)))  # b.android.com/179836
40     def test_inferior_asserting_register(self):
41         """Test that lldb reliably reads registers from the inferior after asserting (command)."""
42         self.build()
43         self.inferior_asserting_registers()
44
45     @expectedFailureAll(
46         oslist=["windows"],
47         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
48     @expectedFailureAll(
49         oslist=["linux"],
50         archs=[
51             "aarch64",
52             "arm"],
53         bugnumber="llvm.org/pr25338")
54     @expectedFailureAll(bugnumber="llvm.org/pr26592", triple='^mips')
55     def test_inferior_asserting_disassemble(self):
56         """Test that lldb reliably disassembles frames after asserting (command)."""
57         self.build()
58         self.inferior_asserting_disassemble()
59
60     @add_test_categories(['pyapi'])
61     @expectedFailureAll(
62         oslist=["windows"],
63         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
64     def test_inferior_asserting_python(self):
65         """Test that lldb reliably catches the inferior asserting (Python API)."""
66         self.build()
67         self.inferior_asserting_python()
68
69     @expectedFailureAll(
70         oslist=["windows"],
71         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
72     @expectedFailureAll(
73         oslist=["linux"],
74         archs=[
75             "aarch64",
76             "arm"],
77         bugnumber="llvm.org/pr25338")
78     @expectedFailureAll(bugnumber="llvm.org/pr26592", triple='^mips')
79     def test_inferior_asserting_expr(self):
80         """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
81         self.build()
82         self.inferior_asserting_expr()
83
84     @expectedFailureAll(
85         oslist=["windows"],
86         bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
87     @expectedFailureAll(
88         oslist=["linux"],
89         archs=[
90             "aarch64",
91             "arm"],
92         bugnumber="llvm.org/pr25338")
93     @expectedFailureAll(bugnumber="llvm.org/pr26592", triple='^mips')
94     def test_inferior_asserting_step(self):
95         """Test that lldb functions correctly after stepping through a call to assert()."""
96         self.build()
97         self.inferior_asserting_step()
98
99     def set_breakpoint(self, line):
100         lldbutil.run_break_set_by_file_and_line(
101             self, "main.c", line, num_expected_locations=1, loc_exact=True)
102
103     def check_stop_reason(self):
104         matched = lldbplatformutil.match_android_device(
105             self.getArchitecture(), valid_api_levels=list(range(1, 16 + 1)))
106         if matched:
107             # On android until API-16 the abort() call ended in a sigsegv
108             # instead of in a sigabrt
109             stop_reason = 'stop reason = signal SIGSEGV'
110         else:
111             stop_reason = 'stop reason = signal SIGABRT'
112
113         # The stop reason of the thread should be an abort signal or exception.
114         self.expect("thread list", STOPPED_DUE_TO_ASSERT,
115                     substrs=['stopped',
116                              stop_reason])
117
118         return stop_reason
119
120     def setUp(self):
121         # Call super's setUp().
122         TestBase.setUp(self)
123         # Find the line number of the call to assert.
124         self.line = line_number('main.c', '// Assert here.')
125
126     def inferior_asserting(self):
127         """Inferior asserts upon launching; lldb should catch the event and stop."""
128         exe = os.path.join(os.getcwd(), "a.out")
129         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
130
131         self.runCmd("run", RUN_SUCCEEDED)
132         stop_reason = self.check_stop_reason()
133
134         # And it should report a backtrace that includes the assert site.
135         self.expect("thread backtrace all",
136                     substrs=[stop_reason, 'main', 'argc', 'argv'])
137
138         # And it should report the correct line number.
139         self.expect("thread backtrace all",
140                     substrs=[stop_reason,
141                              'main.c:%d' % self.line])
142
143     def inferior_asserting_python(self):
144         """Inferior asserts upon launching; lldb should catch the event and stop."""
145         exe = os.path.join(os.getcwd(), "a.out")
146
147         target = self.dbg.CreateTarget(exe)
148         self.assertTrue(target, VALID_TARGET)
149
150         # Now launch the process, and do not stop at entry point.
151         # Both argv and envp are null.
152         process = target.LaunchSimple(
153             None, None, self.get_process_working_directory())
154
155         if process.GetState() != lldb.eStateStopped:
156             self.fail("Process should be in the 'stopped' state, "
157                       "instead the actual state is: '%s'" %
158                       lldbutil.state_type_to_str(process.GetState()))
159
160         thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
161         if not thread:
162             self.fail("Fail to stop the thread upon assert")
163
164         if self.TraceOn():
165             lldbutil.print_stacktrace(thread)
166
167     def inferior_asserting_registers(self):
168         """Test that lldb can read registers after asserting."""
169         exe = os.path.join(os.getcwd(), "a.out")
170         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
171
172         self.runCmd("run", RUN_SUCCEEDED)
173         self.check_stop_reason()
174
175         # lldb should be able to read from registers from the inferior after
176         # asserting.
177         lldbplatformutil.check_first_register_readable(self)
178
179     def inferior_asserting_disassemble(self):
180         """Test that lldb can disassemble frames after asserting."""
181         exe = os.path.join(os.getcwd(), "a.out")
182
183         # Create a target by the debugger.
184         target = self.dbg.CreateTarget(exe)
185         self.assertTrue(target, VALID_TARGET)
186
187         # Launch the process, and do not stop at the entry point.
188         target.LaunchSimple(None, None, self.get_process_working_directory())
189         self.check_stop_reason()
190
191         process = target.GetProcess()
192         self.assertTrue(process.IsValid(), "current process is valid")
193
194         thread = process.GetThreadAtIndex(0)
195         self.assertTrue(thread.IsValid(), "current thread is valid")
196
197         lastframeID = thread.GetFrameAtIndex(
198             thread.GetNumFrames() - 1).GetFrameID()
199
200         isi386Arch = False
201         if "i386" in self.getArchitecture():
202             isi386Arch = True
203
204         # lldb should be able to disassemble frames from the inferior after
205         # asserting.
206         for frame in thread:
207             self.assertTrue(frame.IsValid(), "current frame is valid")
208
209             self.runCmd("frame select " +
210                         str(frame.GetFrameID()), RUN_SUCCEEDED)
211
212             # Don't expect the function name to be in the disassembly as the assert
213             # function might be a no-return function where the PC is past the end
214             # of the function and in the next function. We also can't back the PC up
215             # because we don't know how much to back it up by on targets with opcodes
216             # that have differing sizes
217             pc_backup_offset = 1
218             if frame.GetFrameID() == 0:
219                 pc_backup_offset = 0
220             if isi386Arch:
221                 if lastframeID == frame.GetFrameID():
222                     pc_backup_offset = 0
223             self.expect(
224                 "disassemble -a %s" %
225                 (frame.GetPC() -
226                  pc_backup_offset),
227                 substrs=['<+0>: '])
228
229     def check_expr_in_main(self, thread):
230         depth = thread.GetNumFrames()
231         for i in range(depth):
232             frame = thread.GetFrameAtIndex(i)
233             self.assertTrue(frame.IsValid(), "current frame is valid")
234             if self.TraceOn():
235                 print(
236                     "Checking if function %s is main" %
237                     frame.GetFunctionName())
238
239             if 'main' == frame.GetFunctionName():
240                 frame_id = frame.GetFrameID()
241                 self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
242                 self.expect("p argc", substrs=['(int)', ' = 1'])
243                 self.expect("p hello_world", substrs=['Hello'])
244                 self.expect("p argv[0]", substrs=['a.out'])
245                 self.expect("p null_ptr", substrs=['= 0x0'])
246                 return True
247         return False
248
249     def inferior_asserting_expr(self):
250         """Test that the lldb expression interpreter can read symbols after asserting."""
251         exe = os.path.join(os.getcwd(), "a.out")
252
253         # Create a target by the debugger.
254         target = self.dbg.CreateTarget(exe)
255         self.assertTrue(target, VALID_TARGET)
256
257         # Launch the process, and do not stop at the entry point.
258         target.LaunchSimple(None, None, self.get_process_working_directory())
259         self.check_stop_reason()
260
261         process = target.GetProcess()
262         self.assertTrue(process.IsValid(), "current process is valid")
263
264         thread = process.GetThreadAtIndex(0)
265         self.assertTrue(thread.IsValid(), "current thread is valid")
266
267         # The lldb expression interpreter should be able to read from addresses
268         # of the inferior after a call to assert().
269         self.assertTrue(
270             self.check_expr_in_main(thread),
271             "cannot find 'main' in the backtrace")
272
273     def inferior_asserting_step(self):
274         """Test that lldb functions correctly after stepping through a call to assert()."""
275         exe = os.path.join(os.getcwd(), "a.out")
276
277         # Create a target by the debugger.
278         target = self.dbg.CreateTarget(exe)
279         self.assertTrue(target, VALID_TARGET)
280
281         # Launch the process, and do not stop at the entry point.
282         self.set_breakpoint(self.line)
283         target.LaunchSimple(None, None, self.get_process_working_directory())
284
285         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
286                     substrs=['main.c:%d' % self.line,
287                              'stop reason = breakpoint'])
288
289         self.runCmd("next")
290         stop_reason = self.check_stop_reason()
291
292         # lldb should be able to read from registers from the inferior after
293         # asserting.
294         if "x86_64" in self.getArchitecture():
295             self.expect("register read rbp", substrs=['rbp = 0x'])
296         if "i386" in self.getArchitecture():
297             self.expect("register read ebp", substrs=['ebp = 0x'])
298
299         process = target.GetProcess()
300         self.assertTrue(process.IsValid(), "current process is valid")
301
302         thread = process.GetThreadAtIndex(0)
303         self.assertTrue(thread.IsValid(), "current thread is valid")
304
305         # The lldb expression interpreter should be able to read from addresses
306         # of the inferior after a call to assert().
307         self.assertTrue(
308             self.check_expr_in_main(thread),
309             "cannot find 'main' in the backtrace")
310
311         # And it should report the correct line number.
312         self.expect("thread backtrace all",
313                     substrs=[stop_reason,
314                              'main.c:%d' % self.line])