blob: ccf4d61f222d5cb61ac428093c647cb675f404f3 [file] [log] [blame]
Ashok Thirumurthib4e51342013-05-17 15:35:15 +00001"""Test that lldb functions correctly after the inferior has asserted."""
2
Zachary Turner35d017f2015-10-23 17:04:29 +00003from __future__ import print_function
4
Zachary Turner77db4a82015-10-22 20:06:20 +00005import lldb_shared
6
Ashok Thirumurthib4e51342013-05-17 15:35:15 +00007import os, time
Tamas Berghammer2e169022015-04-02 11:07:55 +00008import lldb, lldbutil, lldbplatformutil
Ashok Thirumurthib4e51342013-05-17 15:35:15 +00009from lldbtest import *
10
11class AssertingInferiorTestCase(TestBase):
12
Greg Clayton4570d3e2013-12-10 23:19:29 +000013 mydir = TestBase.compute_mydir(__file__)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000014
Enrico Granatacf3ab582014-10-17 01:11:29 +000015 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000016 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000017 def test_inferior_asserting(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000018 """Test that lldb reliably catches the inferior asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000019 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000020 self.inferior_asserting()
21
Zachary Turner80c2c602014-12-09 19:28:00 +000022 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Zachary Turner744cd5d2015-10-26 16:49:57 +000023 @expectedFailureAndroid(api_levels=list(range(16 + 1))) # b.android.com/179836
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000024 def test_inferior_asserting_register(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000025 """Test that lldb reliably reads registers from the inferior after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000026 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000027 self.inferior_asserting_registers()
28
Enrico Granatacf3ab582014-10-17 01:11:29 +000029 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000030 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000031 def test_inferior_asserting_disassemble(self):
Ed Maste34bdbbd2013-09-13 15:34:59 +000032 """Test that lldb reliably disassembles frames after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000033 self.build()
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +000034 self.inferior_asserting_disassemble()
35
Pavel Labathdc8b2d32015-10-26 09:28:32 +000036 @add_test_categories(['pyapi'])
Zachary Turner80c2c602014-12-09 19:28:00 +000037 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000038 def test_inferior_asserting_python(self):
39 """Test that lldb reliably catches the inferior asserting (Python API)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000040 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000041 self.inferior_asserting_python()
42
Enrico Granatacf3ab582014-10-17 01:11:29 +000043 @expectedFailurei386('llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly')
Zachary Turner80c2c602014-12-09 19:28:00 +000044 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000045 def test_inferior_asserting_expr(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000046 """Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000047 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000048 self.inferior_asserting_expr()
49
Enrico Granatacf3ab582014-10-17 01:11:29 +000050 @expectedFailurei386("llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly")
Zachary Turner80c2c602014-12-09 19:28:00 +000051 @expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000052 def test_inferior_asserting_step(self):
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000053 """Test that lldb functions correctly after stepping through a call to assert()."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000054 self.build()
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000055 self.inferior_asserting_step()
56
57 def set_breakpoint(self, line):
58 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
59
60 def check_stop_reason(self):
Zachary Turner744cd5d2015-10-26 16:49:57 +000061 if matchAndroid(api_levels=list(range(1, 16+1)))(self):
Tamas Berghammerb285e9e2015-10-02 12:00:04 +000062 # On android until API-16 the abort() call ended in a sigsegv instead of in a sigabrt
63 stop_reason = 'stop reason = signal SIGSEGV'
64 else:
65 stop_reason = 'stop reason = signal SIGABRT'
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000066
67 # The stop reason of the thread should be an abort signal or exception.
68 self.expect("thread list", STOPPED_DUE_TO_ASSERT,
69 substrs = ['stopped',
70 stop_reason])
71
72 return stop_reason
73
74 def setUp(self):
75 # Call super's setUp().
76 TestBase.setUp(self)
77 # Find the line number of the call to assert.
78 self.line = line_number('main.c', '// Assert here.')
79
80 def inferior_asserting(self):
81 """Inferior asserts upon launching; lldb should catch the event and stop."""
82 exe = os.path.join(os.getcwd(), "a.out")
83 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
84
Sean Callanan05834cd2015-07-01 23:56:30 +000085 self.runCmd("run", RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +000086 stop_reason = self.check_stop_reason()
87
88 # And it should report a backtrace that includes the assert site.
89 self.expect("thread backtrace all",
90 substrs = [stop_reason, 'main', 'argc', 'argv'])
91
92 # And it should report the correct line number.
93 self.expect("thread backtrace all",
94 substrs = [stop_reason,
95 'main.c:%d' % self.line])
96
97 def inferior_asserting_python(self):
98 """Inferior asserts upon launching; lldb should catch the event and stop."""
99 exe = os.path.join(os.getcwd(), "a.out")
100
101 target = self.dbg.CreateTarget(exe)
102 self.assertTrue(target, VALID_TARGET)
103
104 # Now launch the process, and do not stop at entry point.
105 # Both argv and envp are null.
Greg Claytonc6947512013-12-13 19:18:59 +0000106 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000107
108 if process.GetState() != lldb.eStateStopped:
109 self.fail("Process should be in the 'stopped' state, "
110 "instead the actual state is: '%s'" %
111 lldbutil.state_type_to_str(process.GetState()))
112
113 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
114 if not thread:
115 self.fail("Fail to stop the thread upon assert")
116
117 if self.TraceOn():
118 lldbutil.print_stacktrace(thread)
119
120 def inferior_asserting_registers(self):
121 """Test that lldb can read registers after asserting."""
122 exe = os.path.join(os.getcwd(), "a.out")
123 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
124
Sean Callanan05834cd2015-07-01 23:56:30 +0000125 self.runCmd("run", RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000126 self.check_stop_reason()
127
128 # lldb should be able to read from registers from the inferior after asserting.
Tamas Berghammer2e169022015-04-02 11:07:55 +0000129 lldbplatformutil.check_first_register_readable(self)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000130
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000131 def inferior_asserting_disassemble(self):
132 """Test that lldb can disassemble frames after asserting."""
133 exe = os.path.join(os.getcwd(), "a.out")
134
135 # Create a target by the debugger.
136 target = self.dbg.CreateTarget(exe)
137 self.assertTrue(target, VALID_TARGET)
138
139 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000140 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000141 self.check_stop_reason()
142
143 process = target.GetProcess()
144 self.assertTrue(process.IsValid(), "current process is valid")
145
146 thread = process.GetThreadAtIndex(0)
147 self.assertTrue(thread.IsValid(), "current thread is valid")
148
149 # lldb should be able to disassemble frames from the inferior after asserting.
150 for frame in thread:
151 self.assertTrue(frame.IsValid(), "current frame is valid")
152
Sean Callanan05834cd2015-07-01 23:56:30 +0000153 self.runCmd("frame select " + str(frame.GetFrameID()), RUN_SUCCEEDED)
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000154
Greg Clayton9485dcf2014-01-10 22:22:44 +0000155 # Don't expect the function name to be in the disassembly as the assert
156 # function might be a no-return function where the PC is past the end
157 # of the function and in the next function. We also can't back the PC up
158 # because we don't know how much to back it up by on targets with opcodes
159 # that have differing sizes
Jason Molendaaff1b352014-10-10 23:07:36 +0000160 pc_backup_offset = 1
161 if frame.GetFrameID() == 0:
162 pc_backup_offset = 0
163 self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
Jason Molendac980fa92015-02-13 23:24:21 +0000164 substrs = ['<+0>: '])
Ashok Thirumurthicd20ee82013-07-23 17:20:17 +0000165
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000166 def check_expr_in_main(self, thread):
167 depth = thread.GetNumFrames()
168 for i in range(depth):
169 frame = thread.GetFrameAtIndex(i)
170 self.assertTrue(frame.IsValid(), "current frame is valid")
171 if self.TraceOn():
Zachary Turner35d017f2015-10-23 17:04:29 +0000172 print("Checking if function %s is main" % frame.GetFunctionName())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000173
174 if 'main' == frame.GetFunctionName():
175 frame_id = frame.GetFrameID()
Sean Callanan05834cd2015-07-01 23:56:30 +0000176 self.runCmd("frame select " + str(frame_id), RUN_SUCCEEDED)
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000177 self.expect("p argc", substrs = ['(int)', ' = 1'])
178 self.expect("p hello_world", substrs = ['Hello'])
179 self.expect("p argv[0]", substrs = ['a.out'])
180 self.expect("p null_ptr", substrs = ['= 0x0'])
181 return True
182 return False
183
184 def inferior_asserting_expr(self):
185 """Test that the lldb expression interpreter can read symbols after asserting."""
186 exe = os.path.join(os.getcwd(), "a.out")
187
188 # Create a target by the debugger.
189 target = self.dbg.CreateTarget(exe)
190 self.assertTrue(target, VALID_TARGET)
191
192 # Launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000193 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000194 self.check_stop_reason()
195
196 process = target.GetProcess()
197 self.assertTrue(process.IsValid(), "current process is valid")
198
199 thread = process.GetThreadAtIndex(0)
200 self.assertTrue(thread.IsValid(), "current thread is valid")
201
202 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
203 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
204
205 def inferior_asserting_step(self):
206 """Test that lldb functions correctly after stepping through a call to assert()."""
207 exe = os.path.join(os.getcwd(), "a.out")
208
209 # Create a target by the debugger.
210 target = self.dbg.CreateTarget(exe)
211 self.assertTrue(target, VALID_TARGET)
212
213 # Launch the process, and do not stop at the entry point.
214 self.set_breakpoint(self.line)
Greg Claytonc6947512013-12-13 19:18:59 +0000215 target.LaunchSimple (None, None, self.get_process_working_directory())
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000216
217 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
218 substrs = ['main.c:%d' % self.line,
219 'stop reason = breakpoint'])
220
221 self.runCmd("next")
222 stop_reason = self.check_stop_reason()
223
224 # lldb should be able to read from registers from the inferior after asserting.
225 if "x86_64" in self.getArchitecture():
226 self.expect("register read rbp", substrs = ['rbp = 0x'])
227 if "i386" in self.getArchitecture():
228 self.expect("register read ebp", substrs = ['ebp = 0x'])
229
230 process = target.GetProcess()
231 self.assertTrue(process.IsValid(), "current process is valid")
232
233 thread = process.GetThreadAtIndex(0)
234 self.assertTrue(thread.IsValid(), "current thread is valid")
235
236 # The lldb expression interpreter should be able to read from addresses of the inferior after a call to assert().
237 self.assertTrue(self.check_expr_in_main(thread), "cannot find 'main' in the backtrace")
238
239 # And it should report the correct line number.
240 self.expect("thread backtrace all",
241 substrs = [stop_reason,
242 'main.c:%d' % self.line])