blob: de74b7171d3108bca995ea4924f4aa612653278e [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
Tamas Berghammer2e169022015-04-02 11:07:55 +00005import lldb, lldbutil, lldbplatformutil
Ashok Thirumurthib4e51342013-05-17 15:35:15 +00006from 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
Enrico Granatacf3ab582014-10-17 01:11:29 +000012 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000013 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000014 def test_inferior_asserting(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000015 """Test that lldb reliably catches the inferior asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000016 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000017 self.inferior_asserting()
18
Zachary Turner80c2c602014-12-09 19:28:00 +000019 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Chaoren Lin845f40a2015-08-03 23:59:41 +000020 @expectedFailureAndroid(api_levels=range(16 + 1)) # b.android.com/179836
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000021 def test_inferior_asserting_register(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000022 """Test that lldb reliably reads registers from the inferior after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000023 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000024 self.inferior_asserting_registers()
25
Enrico Granatacf3ab582014-10-17 01:11:29 +000026 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000027 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000028 def test_inferior_asserting_disassemble(self):
Ed Maste34bdbbd2013-09-13 15:34:59 +000029 """Test that lldb reliably disassembles frames after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000030 self.build()
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000031 self.inferior_asserting_disassemble()
32
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000033 @python_api_test
Zachary Turner80c2c602014-12-09 19:28:00 +000034 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000035 def test_inferior_asserting_python(self):
36 """Test that lldb reliably catches the inferior asserting (Python API)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000037 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000038 self.inferior_asserting_python()
39
Enrico Granatacf3ab582014-10-17 01:11:29 +000040 @expectedFailurei386('llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly')
Zachary Turner80c2c602014-12-09 19:28:00 +000041 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000042 def test_inferior_asserting_expr(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000043 """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000044 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000045 self.inferior_asserting_expr()
46
Enrico Granatacf3ab582014-10-17 01:11:29 +000047 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000048 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000049 def test_inferior_asserting_step(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000050 """Test that lldb functions correctly after stepping through a call to assert()."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000051 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000052 self.inferior_asserting_step()
53
54 def set_breakpoint(self, line):
55 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
56
57 def check_stop_reason(self):
58 stop_reason = 'stop reason = signal SIGABRT'
59
60 # The stop reason of the thread should be an abort signal or exception.
61 self.expect("thread list", STOPPED_DUE_TO_ASSERT,
62 substrs = ['stopped',
63 stop_reason])
64
65 return stop_reason
66
67 def setUp(self):
68 # Call super's setUp().
69 TestBase.setUp(self)
70 # Find the line number of the call to assert.
71 self.line = line_number('main.c', '// Assert here.')
72
73 def inferior_asserting(self):
74 """Inferior asserts upon launching; lldb should catch the event and stop."""
75 exe = os.path.join(os.getcwd(), "a.out")
76 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
77
Sean Callanan05834cd2015-07-01 23:56:30 +000078 self.runCmd("run", RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000079 stop_reason = self.check_stop_reason()
80
81 # And it should report a backtrace that includes the assert site.
82 self.expect("thread backtrace all",
83 substrs = [stop_reason, 'main', 'argc', 'argv'])
84
85 # And it should report the correct line number.
86 self.expect("thread backtrace all",
87 substrs = [stop_reason,
88 'main.c:%d' % self.line])
89
90 def inferior_asserting_python(self):
91 """Inferior asserts upon launching; lldb should catch the event and stop."""
92 exe = os.path.join(os.getcwd(), "a.out")
93
94 target = self.dbg.CreateTarget(exe)
95 self.assertTrue(target, VALID_TARGET)
96
97 # Now launch the process, and do not stop at entry point.
98 # Both argv and envp are null.
Greg Claytonc6947512013-12-13 19:18:59 +000099 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000100
101 if process.GetState() != lldb.eStateStopped:
102 self.fail("Process should be in the 'stopped' state, "
103 "instead the actual state is: '%s'" %
104 lldbutil.state_type_to_str(process.GetState()))
105
106 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
107 if not thread:
108 self.fail("Fail to stop the thread upon assert")
109
110 if self.TraceOn():
111 lldbutil.print_stacktrace(thread)
112
113 def inferior_asserting_registers(self):
114 """Test that lldb can read registers after asserting."""
115 exe = os.path.join(os.getcwd(), "a.out")
116 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
117
Sean Callanan05834cd2015-07-01 23:56:30 +0000118 self.runCmd("run", RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000119 self.check_stop_reason()
120
121 # lldb should be able to read from registers from the inferior after asserting.
Tamas Berghammer2e169022015-04-02 11:07:55 +0000122 lldbplatformutil.check_first_register_readable(self)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000123
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000124 def inferior_asserting_disassemble(self):
125 """Test that lldb can disassemble frames after asserting."""
126 exe = os.path.join(os.getcwd(), "a.out")
127
128 # Create a target by the debugger.
129 target = self.dbg.CreateTarget(exe)
130 self.assertTrue(target, VALID_TARGET)
131
132 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000133 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000134 self.check_stop_reason()
135
136 process = target.GetProcess()
137 self.assertTrue(process.IsValid(), "current process is valid")
138
139 thread = process.GetThreadAtIndex(0)
140 self.assertTrue(thread.IsValid(), "current thread is valid")
141
142 # lldb should be able to disassemble frames from the inferior after asserting.
143 for frame in thread:
144 self.assertTrue(frame.IsValid(), "current frame is valid")
145
Sean Callanan05834cd2015-07-01 23:56:30 +0000146 self.runCmd("frame select " + str(frame.GetFrameID()), RUN_SUCCEEDED)
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000147
Greg Clayton9485dcf2014-01-10 22:22:44 +0000148 # Don't expect the function name to be in the disassembly as the assert
149 # function might be a no-return function where the PC is past the end
150 # of the function and in the next function. We also can't back the PC up
151 # because we don't know how much to back it up by on targets with opcodes
152 # that have differing sizes
Jason Molendaaff1b352014-10-10 23:07:36 +0000153 pc_backup_offset = 1
154 if frame.GetFrameID() == 0:
155 pc_backup_offset = 0
156 self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
Jason Molendac980fa92015-02-13 23:24:21 +0000157 substrs = ['<+0>: '])
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000158
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000159 def check_expr_in_main(self, thread):
160 depth = thread.GetNumFrames()
161 for i in range(depth):
162 frame = thread.GetFrameAtIndex(i)
163 self.assertTrue(frame.IsValid(), "current frame is valid")
164 if self.TraceOn():
165 print "Checking if function %s is main" % frame.GetFunctionName()
166
167 if 'main' == frame.GetFunctionName():
168 frame_id = frame.GetFrameID()
Sean Callanan05834cd2015-07-01 23:56:30 +0000169 self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000170 self.expect("p argc", substrs = ['(int)', ' = 1'])
171 self.expect("p hello_world", substrs = ['Hello'])
172 self.expect("p argv[0]", substrs = ['a.out'])
173 self.expect("p null_ptr", substrs = ['= 0x0'])
174 return True
175 return False
176
177 def inferior_asserting_expr(self):
178 """Test that the lldb expression interpreter can read symbols after asserting."""
179 exe = os.path.join(os.getcwd(), "a.out")
180
181 # Create a target by the debugger.
182 target = self.dbg.CreateTarget(exe)
183 self.assertTrue(target, VALID_TARGET)
184
185 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000186 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000187 self.check_stop_reason()
188
189 process = target.GetProcess()
190 self.assertTrue(process.IsValid(), "current process is valid")
191
192 thread = process.GetThreadAtIndex(0)
193 self.assertTrue(thread.IsValid(), "current thread is valid")
194
195 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
196 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
197
198 def inferior_asserting_step(self):
199 """Test that lldb functions correctly after stepping through a call to assert()."""
200 exe = os.path.join(os.getcwd(), "a.out")
201
202 # Create a target by the debugger.
203 target = self.dbg.CreateTarget(exe)
204 self.assertTrue(target, VALID_TARGET)
205
206 # Launch the process, and do not stop at the entry point.
207 self.set_breakpoint(self.line)
Greg Claytonc6947512013-12-13 19:18:59 +0000208 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000209
210 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
211 substrs = ['main.c:%d' % self.line,
212 'stop reason = breakpoint'])
213
214 self.runCmd("next")
215 stop_reason = self.check_stop_reason()
216
217 # lldb should be able to read from registers from the inferior after asserting.
218 if "x86_64" in self.getArchitecture():
219 self.expect("register read rbp", substrs = ['rbp = 0x'])
220 if "i386" in self.getArchitecture():
221 self.expect("register read ebp", substrs = ['ebp = 0x'])
222
223 process = target.GetProcess()
224 self.assertTrue(process.IsValid(), "current process is valid")
225
226 thread = process.GetThreadAtIndex(0)
227 self.assertTrue(thread.IsValid(), "current thread is valid")
228
229 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
230 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
231
232 # And it should report the correct line number.
233 self.expect("thread backtrace all",
234 substrs = [stop_reason,
235 'main.c:%d' % self.line])
236
237if __name__ == '__main__':
238 import atexit
239 lldb.SBDebugger.Initialize()
240 atexit.register(lambda: lldb.SBDebugger.Terminate())
241 unittest2.main()