1 """Test that lldb functions correctly after the inferior has asserted."""
3 from __future__ import print_function
9 from lldbsuite.test import lldbutil
10 from lldbsuite.test import lldbplatformutil
11 from lldbsuite.test.decorators import *
12 from lldbsuite.test.lldbtest import *
15 class AssertingInferiorTestCase(TestBase):
17 mydir = TestBase.compute_mydir(__file__)
21 bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
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)."""
30 self.inferior_asserting()
34 bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
35 @expectedFailureAndroid(
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)."""
43 self.inferior_asserting_registers()
47 bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
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)."""
58 self.inferior_asserting_disassemble()
60 @add_test_categories(['pyapi'])
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)."""
67 self.inferior_asserting_python()
71 bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
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)."""
82 self.inferior_asserting_expr()
86 bugnumber="llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
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()."""
97 self.inferior_asserting_step()
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)
103 def check_stop_reason(self):
104 matched = lldbplatformutil.match_android_device(
105 self.getArchitecture(), valid_api_levels=list(range(1, 16 + 1)))
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'
111 stop_reason = 'stop reason = signal SIGABRT'
113 # The stop reason of the thread should be an abort signal or exception.
114 self.expect("thread list", STOPPED_DUE_TO_ASSERT,
121 # Call super's setUp().
123 # Find the line number of the call to assert.
124 self.line = line_number('main.c', '// Assert here.')
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)
131 self.runCmd("run", RUN_SUCCEEDED)
132 stop_reason = self.check_stop_reason()
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'])
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])
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")
147 target = self.dbg.CreateTarget(exe)
148 self.assertTrue(target, VALID_TARGET)
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())
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()))
160 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
162 self.fail("Fail to stop the thread upon assert")
165 lldbutil.print_stacktrace(thread)
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)
172 self.runCmd("run", RUN_SUCCEEDED)
173 self.check_stop_reason()
175 # lldb should be able to read from registers from the inferior after
177 lldbplatformutil.check_first_register_readable(self)
179 def inferior_asserting_disassemble(self):
180 """Test that lldb can disassemble frames after asserting."""
181 exe = os.path.join(os.getcwd(), "a.out")
183 # Create a target by the debugger.
184 target = self.dbg.CreateTarget(exe)
185 self.assertTrue(target, VALID_TARGET)
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()
191 process = target.GetProcess()
192 self.assertTrue(process.IsValid(), "current process is valid")
194 thread = process.GetThreadAtIndex(0)
195 self.assertTrue(thread.IsValid(), "current thread is valid")
197 lastframeID = thread.GetFrameAtIndex(
198 thread.GetNumFrames() - 1).GetFrameID()
201 if "i386" in self.getArchitecture():
204 # lldb should be able to disassemble frames from the inferior after
207 self.assertTrue(frame.IsValid(), "current frame is valid")
209 self.runCmd("frame select " +
210 str(frame.GetFrameID()), RUN_SUCCEEDED)
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
218 if frame.GetFrameID() == 0:
221 if lastframeID == frame.GetFrameID():
224 "disassemble -a %s" %
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")
236 "Checking if function %s is main" %
237 frame.GetFunctionName())
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'])
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")
253 # Create a target by the debugger.
254 target = self.dbg.CreateTarget(exe)
255 self.assertTrue(target, VALID_TARGET)
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()
261 process = target.GetProcess()
262 self.assertTrue(process.IsValid(), "current process is valid")
264 thread = process.GetThreadAtIndex(0)
265 self.assertTrue(thread.IsValid(), "current thread is valid")
267 # The lldb expression interpreter should be able to read from addresses
268 # of the inferior after a call to assert().
270 self.check_expr_in_main(thread),
271 "cannot find 'main' in the backtrace")
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")
277 # Create a target by the debugger.
278 target = self.dbg.CreateTarget(exe)
279 self.assertTrue(target, VALID_TARGET)
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())
285 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
286 substrs=['main.c:%d' % self.line,
287 'stop reason = breakpoint'])
290 stop_reason = self.check_stop_reason()
292 # lldb should be able to read from registers from the inferior after
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'])
299 process = target.GetProcess()
300 self.assertTrue(process.IsValid(), "current process is valid")
302 thread = process.GetThreadAtIndex(0)
303 self.assertTrue(thread.IsValid(), "current thread is valid")
305 # The lldb expression interpreter should be able to read from addresses
306 # of the inferior after a call to assert().
308 self.check_expr_in_main(thread),
309 "cannot find 'main' in the backtrace")
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])