blob: a15106f1ce32448943a79504328e8d39b7d3ac57 [file] [log] [blame]
Ashok Thirumurthib4e51342013-05-17 15:35:15 +00001"""Test that lldb functions correctly after the inferior has asserted."""
2
3import os, time
4import unittest2
5import lldb, lldbutil
6from lldbtest import *
7
8class AssertingInferiorTestCase(TestBase):
9
Greg Clayton4570d3e2013-12-10 23:19:29 +000010 mydir = TestBase.compute_mydir(__file__)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000011
12 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
Enrico Granata4a2dc3b2013-10-31 23:05:35 +000013 @unittest2.expectedFailure("rdar://15367233")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000014 def test_inferior_asserting_dsym(self):
15 """Test that lldb reliably catches the inferior asserting (command)."""
16 self.buildDsym()
17 self.inferior_asserting()
18
Enrico Granatacf3ab582014-10-17 01:11:29 +000019 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Ed Masteec4f47e2014-04-22 13:42:05 +000020 @expectedFailureDarwin("rdar://15367233")
Zachary Turner80c2c602014-12-09 19:28:00 +000021 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000022 def test_inferior_asserting_dwarf(self):
23 """Test that lldb reliably catches the inferior asserting (command)."""
24 self.buildDwarf()
25 self.inferior_asserting()
26
27 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
28 def test_inferior_asserting_registers_dsym(self):
29 """Test that lldb reliably reads registers from the inferior after asserting (command)."""
30 self.buildDsym()
31 self.inferior_asserting_registers()
32
Zachary Turner80c2c602014-12-09 19:28:00 +000033 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000034 def test_inferior_asserting_register_dwarf(self):
35 """Test that lldb reliably reads registers from the inferior after asserting (command)."""
36 self.buildDwarf()
37 self.inferior_asserting_registers()
38
Enrico Granatacf3ab582014-10-17 01:11:29 +000039 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
40 @expectedFailureFreeBSD('llvm.org/pr18533 - PC in __assert frame is outside of function')
41 @expectedFailureLinux("PC in __GI___assert_fail frame is just after the function (this is a no-return so there is no epilogue afterwards)")
Zachary Turner80c2c602014-12-09 19:28:00 +000042 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000043 def test_inferior_asserting_disassemble(self):
Ed Maste34bdbbd2013-09-13 15:34:59 +000044 """Test that lldb reliably disassembles frames after asserting (command)."""
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000045 self.buildDefault()
46 self.inferior_asserting_disassemble()
47
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000048 @python_api_test
Zachary Turner80c2c602014-12-09 19:28:00 +000049 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000050 def test_inferior_asserting_python(self):
51 """Test that lldb reliably catches the inferior asserting (Python API)."""
52 self.buildDefault()
53 self.inferior_asserting_python()
54
55 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
Enrico Granata4510a152013-10-31 23:06:54 +000056 @unittest2.expectedFailure("rdar://15367233")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000057 def test_inferior_asserting_expr(self):
58 """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
59 self.buildDsym()
60 self.inferior_asserting_expr()
61
Enrico Granatacf3ab582014-10-17 01:11:29 +000062 @expectedFailurei386('llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly')
Enrico Granata4510a152013-10-31 23:06:54 +000063 @unittest2.expectedFailure("rdar://15367233")
Zachary Turner80c2c602014-12-09 19:28:00 +000064 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000065 def test_inferior_asserting_expr(self):
66 """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
67 self.buildDwarf()
68 self.inferior_asserting_expr()
69
70 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
Enrico Granata7037b3f2013-10-31 23:07:41 +000071 @unittest2.expectedFailure("rdar://15367233")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000072 def test_inferior_asserting_step(self):
73 """Test that lldb functions correctly after stepping through a call to assert()."""
74 self.buildDsym()
75 self.inferior_asserting_step()
76
Enrico Granatacf3ab582014-10-17 01:11:29 +000077 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Ed Masteec4f47e2014-04-22 13:42:05 +000078 @expectedFailureDarwin("rdar://15367233")
Zachary Turner80c2c602014-12-09 19:28:00 +000079 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000080 def test_inferior_asserting_step(self):
81 """Test that lldb functions correctly after stepping through a call to assert()."""
82 self.buildDwarf()
83 self.inferior_asserting_step()
84
85 def set_breakpoint(self, line):
86 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
87
88 def check_stop_reason(self):
89 stop_reason = 'stop reason = signal SIGABRT'
90
91 # The stop reason of the thread should be an abort signal or exception.
92 self.expect("thread list", STOPPED_DUE_TO_ASSERT,
93 substrs = ['stopped',
94 stop_reason])
95
96 return stop_reason
97
98 def setUp(self):
99 # Call super's setUp().
100 TestBase.setUp(self)
101 # Find the line number of the call to assert.
102 self.line = line_number('main.c', '// Assert here.')
103
104 def inferior_asserting(self):
105 """Inferior asserts upon launching; lldb should catch the event and stop."""
106 exe = os.path.join(os.getcwd(), "a.out")
107 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
108
109 self.runCmd("run", RUN_SUCCEEDED)
110 stop_reason = self.check_stop_reason()
111
112 # And it should report a backtrace that includes the assert site.
113 self.expect("thread backtrace all",
114 substrs = [stop_reason, 'main', 'argc', 'argv'])
115
116 # And it should report the correct line number.
117 self.expect("thread backtrace all",
118 substrs = [stop_reason,
119 'main.c:%d' % self.line])
120
121 def inferior_asserting_python(self):
122 """Inferior asserts upon launching; lldb should catch the event and stop."""
123 exe = os.path.join(os.getcwd(), "a.out")
124
125 target = self.dbg.CreateTarget(exe)
126 self.assertTrue(target, VALID_TARGET)
127
128 # Now launch the process, and do not stop at entry point.
129 # Both argv and envp are null.
Greg Claytonc6947512013-12-13 19:18:59 +0000130 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000131
132 if process.GetState() != lldb.eStateStopped:
133 self.fail("Process should be in the 'stopped' state, "
134 "instead the actual state is: '%s'" %
135 lldbutil.state_type_to_str(process.GetState()))
136
137 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
138 if not thread:
139 self.fail("Fail to stop the thread upon assert")
140
141 if self.TraceOn():
142 lldbutil.print_stacktrace(thread)
143
144 def inferior_asserting_registers(self):
145 """Test that lldb can read registers after asserting."""
146 exe = os.path.join(os.getcwd(), "a.out")
147 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
148
149 self.runCmd("run", RUN_SUCCEEDED)
150 self.check_stop_reason()
151
152 # lldb should be able to read from registers from the inferior after asserting.
153 self.expect("register read eax",
154 substrs = ['eax = 0x'])
155
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000156 def inferior_asserting_disassemble(self):
157 """Test that lldb can disassemble frames after asserting."""
158 exe = os.path.join(os.getcwd(), "a.out")
159
160 # Create a target by the debugger.
161 target = self.dbg.CreateTarget(exe)
162 self.assertTrue(target, VALID_TARGET)
163
164 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000165 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000166 self.check_stop_reason()
167
168 process = target.GetProcess()
169 self.assertTrue(process.IsValid(), "current process is valid")
170
171 thread = process.GetThreadAtIndex(0)
172 self.assertTrue(thread.IsValid(), "current thread is valid")
173
174 # lldb should be able to disassemble frames from the inferior after asserting.
175 for frame in thread:
176 self.assertTrue(frame.IsValid(), "current frame is valid")
177
178 self.runCmd("frame select " + str(frame.GetFrameID()), RUN_SUCCEEDED)
179
Greg Clayton9485dcf2014-01-10 22:22:44 +0000180 # Don't expect the function name to be in the disassembly as the assert
181 # function might be a no-return function where the PC is past the end
182 # of the function and in the next function. We also can't back the PC up
183 # because we don't know how much to back it up by on targets with opcodes
184 # that have differing sizes
Jason Molendaaff1b352014-10-10 23:07:36 +0000185 pc_backup_offset = 1
186 if frame.GetFrameID() == 0:
187 pc_backup_offset = 0
188 self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
189 substrs = ['<%s>:' % frame.GetFunctionName()])
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000190
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000191 def check_expr_in_main(self, thread):
192 depth = thread.GetNumFrames()
193 for i in range(depth):
194 frame = thread.GetFrameAtIndex(i)
195 self.assertTrue(frame.IsValid(), "current frame is valid")
196 if self.TraceOn():
197 print "Checking if function %s is main" % frame.GetFunctionName()
198
199 if 'main' == frame.GetFunctionName():
200 frame_id = frame.GetFrameID()
201 self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
202 self.expect("p argc", substrs = ['(int)', ' = 1'])
203 self.expect("p hello_world", substrs = ['Hello'])
204 self.expect("p argv[0]", substrs = ['a.out'])
205 self.expect("p null_ptr", substrs = ['= 0x0'])
206 return True
207 return False
208
209 def inferior_asserting_expr(self):
210 """Test that the lldb expression interpreter can read symbols after asserting."""
211 exe = os.path.join(os.getcwd(), "a.out")
212
213 # Create a target by the debugger.
214 target = self.dbg.CreateTarget(exe)
215 self.assertTrue(target, VALID_TARGET)
216
217 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000218 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000219 self.check_stop_reason()
220
221 process = target.GetProcess()
222 self.assertTrue(process.IsValid(), "current process is valid")
223
224 thread = process.GetThreadAtIndex(0)
225 self.assertTrue(thread.IsValid(), "current thread is valid")
226
227 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
228 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
229
230 def inferior_asserting_step(self):
231 """Test that lldb functions correctly after stepping through a call to assert()."""
232 exe = os.path.join(os.getcwd(), "a.out")
233
234 # Create a target by the debugger.
235 target = self.dbg.CreateTarget(exe)
236 self.assertTrue(target, VALID_TARGET)
237
238 # Launch the process, and do not stop at the entry point.
239 self.set_breakpoint(self.line)
Greg Claytonc6947512013-12-13 19:18:59 +0000240 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000241
242 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
243 substrs = ['main.c:%d' % self.line,
244 'stop reason = breakpoint'])
245
246 self.runCmd("next")
247 stop_reason = self.check_stop_reason()
248
249 # lldb should be able to read from registers from the inferior after asserting.
250 if "x86_64" in self.getArchitecture():
251 self.expect("register read rbp", substrs = ['rbp = 0x'])
252 if "i386" in self.getArchitecture():
253 self.expect("register read ebp", substrs = ['ebp = 0x'])
254
255 process = target.GetProcess()
256 self.assertTrue(process.IsValid(), "current process is valid")
257
258 thread = process.GetThreadAtIndex(0)
259 self.assertTrue(thread.IsValid(), "current thread is valid")
260
261 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
262 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
263
264 # And it should report the correct line number.
265 self.expect("thread backtrace all",
266 substrs = [stop_reason,
267 'main.c:%d' % self.line])
268
269if __name__ == '__main__':
270 import atexit
271 lldb.SBDebugger.Initialize()
272 atexit.register(lambda: lldb.SBDebugger.Terminate())
273 unittest2.main()