blob: 355e0f27e80fdd85c634e8adeb247776fcf0befc [file] [log] [blame]
Johnny Chend61816b2011-03-03 01:41:57 +00001"""
2Test SBTarget APIs.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class TargetAPITestCase(TestBase):
12
13 mydir = os.path.join("python_api", "target")
14
15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000017 @dsym_test
Johnny Chen466c5932011-06-29 22:45:06 +000018 def test_find_global_variables_with_dsym(self):
19 """Exercise SBTaget.FindGlobalVariables() API."""
Johnny Chen086b1b72011-06-30 00:24:31 +000020 d = {'EXE': 'a.out'}
21 self.buildDsym(dictionary=d)
22 self.setTearDownCleanup(dictionary=d)
23 self.find_global_variables('a.out')
Johnny Chen466c5932011-06-29 22:45:06 +000024
Johnny Chen086b1b72011-06-30 00:24:31 +000025 #rdar://problem/9700873
Johnny Chen56b92a72011-07-11 19:15:11 +000026 # Find global variable value fails for dwarf if inferior not started
27 # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94)
28 #
29 # It does not segfaults now. But for dwarf, the variable value is None if
30 # the inferior process does not exist yet. The radar has been updated.
31 #@unittest232.skip("segmentation fault -- skipping")
Johnny Chen466c5932011-06-29 22:45:06 +000032 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000033 @dwarf_test
Johnny Chen466c5932011-06-29 22:45:06 +000034 def test_find_global_variables_with_dwarf(self):
35 """Exercise SBTarget.FindGlobalVariables() API."""
Johnny Chen086b1b72011-06-30 00:24:31 +000036 d = {'EXE': 'b.out'}
37 self.buildDwarf(dictionary=d)
38 self.setTearDownCleanup(dictionary=d)
39 self.find_global_variables('b.out')
Johnny Chen466c5932011-06-29 22:45:06 +000040
41 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
42 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000043 @dsym_test
Johnny Chen4bc80de2011-07-07 22:22:51 +000044 def test_find_functions_with_dsym(self):
45 """Exercise SBTaget.FindFunctions() API."""
46 d = {'EXE': 'a.out'}
47 self.buildDsym(dictionary=d)
48 self.setTearDownCleanup(dictionary=d)
49 self.find_functions('a.out')
50
51 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000052 @dwarf_test
Johnny Chen4bc80de2011-07-07 22:22:51 +000053 def test_find_functions_with_dwarf(self):
54 """Exercise SBTarget.FindFunctions() API."""
55 d = {'EXE': 'b.out'}
56 self.buildDwarf(dictionary=d)
57 self.setTearDownCleanup(dictionary=d)
58 self.find_functions('b.out')
59
60 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
61 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000062 @dsym_test
Johnny Chen787f71f2011-04-22 23:20:17 +000063 def test_get_description_with_dsym(self):
64 """Exercise SBTaget.GetDescription() API."""
65 self.buildDsym()
66 self.get_description()
67
68 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000069 @dwarf_test
Johnny Chen787f71f2011-04-22 23:20:17 +000070 def test_get_description_with_dwarf(self):
71 """Exercise SBTarget.GetDescription() API."""
72 self.buildDwarf()
73 self.get_description()
74
75 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
76 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000077 @dsym_test
Johnny Chen75625aa2011-03-07 22:29:04 +000078 def test_launch_new_process_and_redirect_stdout_with_dsym(self):
79 """Exercise SBTaget.Launch() API."""
80 self.buildDsym()
81 self.launch_new_process_and_redirect_stdout()
82
83 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000084 @dwarf_test
Johnny Chen75625aa2011-03-07 22:29:04 +000085 def test_launch_new_process_and_redirect_stdout_with_dwarf(self):
86 """Exercise SBTarget.Launch() API."""
87 self.buildDwarf()
88 self.launch_new_process_and_redirect_stdout()
89
90 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
91 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000092 @dsym_test
Johnny Chen05178f62011-03-04 23:40:06 +000093 def test_resolve_symbol_context_with_address_with_dsym(self):
94 """Exercise SBTaget.ResolveSymbolContextForAddress() API."""
Johnny Chend61816b2011-03-03 01:41:57 +000095 self.buildDsym()
Johnny Chen05178f62011-03-04 23:40:06 +000096 self.resolve_symbol_context_with_address()
Johnny Chend61816b2011-03-03 01:41:57 +000097
98 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000099 @dwarf_test
Johnny Chen05178f62011-03-04 23:40:06 +0000100 def test_resolve_symbol_context_with_address_with_dwarf(self):
101 """Exercise SBTarget.ResolveSymbolContextForAddress() API."""
Johnny Chend61816b2011-03-03 01:41:57 +0000102 self.buildDwarf()
Johnny Chen05178f62011-03-04 23:40:06 +0000103 self.resolve_symbol_context_with_address()
Johnny Chend61816b2011-03-03 01:41:57 +0000104
105 def setUp(self):
106 # Call super's setUp().
107 TestBase.setUp(self)
108 # Find the line number to of function 'c'.
109 self.line1 = line_number('main.c', '// Find the line number for breakpoint 1 here.')
110 self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.')
111
Johnny Chen086b1b72011-06-30 00:24:31 +0000112 def find_global_variables(self, exe_name):
Johnny Chen466c5932011-06-29 22:45:06 +0000113 """Exercise SBTaget.FindGlobalVariables() API."""
Johnny Chen086b1b72011-06-30 00:24:31 +0000114 exe = os.path.join(os.getcwd(), exe_name)
Johnny Chen466c5932011-06-29 22:45:06 +0000115
116 # Create a target by the debugger.
117 target = self.dbg.CreateTarget(exe)
118 self.assertTrue(target, VALID_TARGET)
119
Johnny Chen56b92a72011-07-11 19:15:11 +0000120 #rdar://problem/9700873
121 # Find global variable value fails for dwarf if inferior not started
122 # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94)
123 #
124 # Remove the lines to create a breakpoint and to start the inferior
125 # which are workarounds for the dwarf case.
126
127 breakpoint = target.BreakpointCreateByLocation('main.c', self.line1)
128 self.assertTrue(breakpoint, VALID_BREAKPOINT)
129
130 # Now launch the process, and do not stop at entry point.
131 process = target.LaunchSimple(None, None, os.getcwd())
132 self.assertTrue(process, PROCESS_IS_VALID)
Jim Ingham4cda6e02011-10-07 22:23:45 +0000133 # Make sure we hit our breakpoint:
134 thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
135 self.assertTrue (len(thread_list) == 1)
Johnny Chen56b92a72011-07-11 19:15:11 +0000136
Johnny Chen086b1b72011-06-30 00:24:31 +0000137 value_list = target.FindGlobalVariables('my_global_var_of_char_type', 3)
Johnny Chen466c5932011-06-29 22:45:06 +0000138 self.assertTrue(value_list.GetSize() == 1)
139 my_global_var = value_list.GetValueAtIndex(0)
Johnny Chen56b92a72011-07-11 19:15:11 +0000140 self.DebugSBValue(my_global_var)
Johnny Chen4bc80de2011-07-07 22:22:51 +0000141 self.assertTrue(my_global_var)
Johnny Chen466c5932011-06-29 22:45:06 +0000142 self.expect(my_global_var.GetName(), exe=False,
143 startstr = "my_global_var_of_char_type")
144 self.expect(my_global_var.GetTypeName(), exe=False,
145 startstr = "char")
146 self.expect(my_global_var.GetValue(), exe=False,
147 startstr = "'X'")
148
Johnny Chen086b1b72011-06-30 00:24:31 +0000149 # While we are at it, let's also exercise the similar SBModule.FindGlobalVariables() API.
150 for m in target.module_iter():
151 if m.GetFileSpec().GetDirectory() == os.getcwd() and m.GetFileSpec().GetFilename() == exe_name:
152 value_list = m.FindGlobalVariables(target, 'my_global_var_of_char_type', 3)
153 self.assertTrue(value_list.GetSize() == 1)
154 self.assertTrue(value_list.GetValueAtIndex(0).GetValue() == "'X'")
155 break
156
Johnny Chen4bc80de2011-07-07 22:22:51 +0000157 def find_functions(self, exe_name):
158 """Exercise SBTaget.FindFunctions() API."""
159 exe = os.path.join(os.getcwd(), exe_name)
160
161 # Create a target by the debugger.
162 target = self.dbg.CreateTarget(exe)
163 self.assertTrue(target, VALID_TARGET)
164
Greg Clayton5569e642012-02-06 01:44:54 +0000165 list = target.FindFunctions('c', lldb.eFunctionNameTypeAuto)
166 self.assertTrue(list.GetSize() == 1)
Johnny Chen4bc80de2011-07-07 22:22:51 +0000167
168 for sc in list:
Johnny Chenf8ae3c72011-07-07 22:45:54 +0000169 self.assertTrue(sc.GetModule().GetFileSpec().GetFilename() == exe_name)
Johnny Chen4bc80de2011-07-07 22:22:51 +0000170 self.assertTrue(sc.GetSymbol().GetName() == 'c')
171
Johnny Chen787f71f2011-04-22 23:20:17 +0000172 def get_description(self):
173 """Exercise SBTaget.GetDescription() API."""
174 exe = os.path.join(os.getcwd(), "a.out")
175
176 # Create a target by the debugger.
177 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000178 self.assertTrue(target, VALID_TARGET)
Johnny Chen787f71f2011-04-22 23:20:17 +0000179
Johnny Chen90256cd2011-04-23 00:13:34 +0000180 from lldbutil import get_description
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000181
182 # get_description() allows no option to mean lldb.eDescriptionLevelBrief.
183 desc = get_description(target)
184 #desc = get_description(target, option=lldb.eDescriptionLevelBrief)
Johnny Chen90256cd2011-04-23 00:13:34 +0000185 if not desc:
Johnny Chen787f71f2011-04-22 23:20:17 +0000186 self.fail("SBTarget.GetDescription() failed")
Johnny Chen90256cd2011-04-23 00:13:34 +0000187 self.expect(desc, exe=False,
Johnny Chen787f71f2011-04-22 23:20:17 +0000188 substrs = ['a.out'])
Johnny Chen90256cd2011-04-23 00:13:34 +0000189 self.expect(desc, exe=False, matching=False,
Johnny Chen787f71f2011-04-22 23:20:17 +0000190 substrs = ['Target', 'Module', 'Breakpoint'])
191
Johnny Chen90256cd2011-04-23 00:13:34 +0000192 desc = get_description(target, option=lldb.eDescriptionLevelFull)
193 if not desc:
Johnny Chen787f71f2011-04-22 23:20:17 +0000194 self.fail("SBTarget.GetDescription() failed")
Johnny Chen90256cd2011-04-23 00:13:34 +0000195 self.expect(desc, exe=False,
Johnny Chen787f71f2011-04-22 23:20:17 +0000196 substrs = ['a.out', 'Target', 'Module', 'Breakpoint'])
197
198
Johnny Chen75625aa2011-03-07 22:29:04 +0000199 def launch_new_process_and_redirect_stdout(self):
200 """Exercise SBTaget.Launch() API with redirected stdout."""
201 exe = os.path.join(os.getcwd(), "a.out")
202
203 # Create a target by the debugger.
204 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000205 self.assertTrue(target, VALID_TARGET)
Johnny Chen75625aa2011-03-07 22:29:04 +0000206
Johnny Chend6481352011-03-07 22:46:30 +0000207 # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done.
208 # We should still see the entire stdout redirected once the process is finished.
209 line = line_number('main.c', '// a(3) -> c(3)')
210 breakpoint = target.BreakpointCreateByLocation('main.c', line)
211
Johnny Chen75625aa2011-03-07 22:29:04 +0000212 # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000213 # The inferior should run to completion after "process.Continue()" call.
Johnny Chen75625aa2011-03-07 22:29:04 +0000214 error = lldb.SBError()
215 process = target.Launch (self.dbg.GetListener(), None, None, None, "stdout.txt", None, None, 0, False, error)
Johnny Chend6481352011-03-07 22:46:30 +0000216 process.Continue()
217 #self.runCmd("process status")
Johnny Chen75625aa2011-03-07 22:29:04 +0000218
219 # The 'stdout.txt' file should now exist.
220 self.assertTrue(os.path.isfile("stdout.txt"),
221 "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.")
222
223 # Read the output file produced by running the program.
224 with open('stdout.txt', 'r') as f:
225 output = f.read()
226
Johnny Chend6481352011-03-07 22:46:30 +0000227 # Let's delete the 'stdout.txt' file as a cleanup step.
228 try:
229 os.remove("stdout.txt")
230 pass
231 except OSError:
232 pass
233
Johnny Chen75625aa2011-03-07 22:29:04 +0000234 self.expect(output, exe=False,
235 substrs = ["a(1)", "b(2)", "a(3)"])
236
237
Johnny Chen05178f62011-03-04 23:40:06 +0000238 def resolve_symbol_context_with_address(self):
239 """Exercise SBTaget.ResolveSymbolContextForAddress() API."""
Johnny Chend61816b2011-03-03 01:41:57 +0000240 exe = os.path.join(os.getcwd(), "a.out")
241
242 # Create a target by the debugger.
243 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000244 self.assertTrue(target, VALID_TARGET)
Johnny Chend61816b2011-03-03 01:41:57 +0000245
246 # Now create the two breakpoints inside function 'a'.
247 breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1)
248 breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2)
Johnny Chened401982011-03-03 19:14:00 +0000249 #print "breakpoint1:", breakpoint1
250 #print "breakpoint2:", breakpoint2
Johnny Chen4ebd0192011-05-24 18:22:45 +0000251 self.assertTrue(breakpoint1 and
Johnny Chend61816b2011-03-03 01:41:57 +0000252 breakpoint1.GetNumLocations() == 1,
253 VALID_BREAKPOINT)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000254 self.assertTrue(breakpoint2 and
Johnny Chend61816b2011-03-03 01:41:57 +0000255 breakpoint2.GetNumLocations() == 1,
256 VALID_BREAKPOINT)
257
258 # Now launch the process, and do not stop at entry point.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000259 process = target.LaunchSimple(None, None, os.getcwd())
260 self.assertTrue(process, PROCESS_IS_VALID)
Johnny Chend61816b2011-03-03 01:41:57 +0000261
262 # Frame #0 should be on self.line1.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000263 self.assertTrue(process.GetState() == lldb.eStateStopped)
264 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chened401982011-03-03 19:14:00 +0000265 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
266 #self.runCmd("process status")
Johnny Chend61816b2011-03-03 01:41:57 +0000267 frame0 = thread.GetFrameAtIndex(0)
268 lineEntry = frame0.GetLineEntry()
269 self.assertTrue(lineEntry.GetLine() == self.line1)
270
271 address1 = lineEntry.GetStartAddress()
272
273 # Continue the inferior, the breakpoint 2 should be hit.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000274 process.Continue()
275 self.assertTrue(process.GetState() == lldb.eStateStopped)
276 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chened401982011-03-03 19:14:00 +0000277 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
278 #self.runCmd("process status")
Johnny Chend61816b2011-03-03 01:41:57 +0000279 frame0 = thread.GetFrameAtIndex(0)
280 lineEntry = frame0.GetLineEntry()
281 self.assertTrue(lineEntry.GetLine() == self.line2)
282
283 address2 = lineEntry.GetStartAddress()
284
Johnny Chened401982011-03-03 19:14:00 +0000285 #print "address1:", address1
286 #print "address2:", address2
Johnny Chend61816b2011-03-03 01:41:57 +0000287
288 # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses from our line entry.
289 context1 = target.ResolveSymbolContextForAddress(address1, lldb.eSymbolContextEverything)
290 context2 = target.ResolveSymbolContextForAddress(address2, lldb.eSymbolContextEverything)
291
Johnny Chen4ebd0192011-05-24 18:22:45 +0000292 self.assertTrue(context1 and context2)
Johnny Chened401982011-03-03 19:14:00 +0000293 #print "context1:", context1
294 #print "context2:", context2
Johnny Chend61816b2011-03-03 01:41:57 +0000295
296 # Verify that the context point to the same function 'a'.
297 symbol1 = context1.GetSymbol()
298 symbol2 = context2.GetSymbol()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000299 self.assertTrue(symbol1 and symbol2)
Johnny Chened401982011-03-03 19:14:00 +0000300 #print "symbol1:", symbol1
301 #print "symbol2:", symbol2
Johnny Chend61816b2011-03-03 01:41:57 +0000302
Johnny Chen9ae98202011-04-23 00:34:56 +0000303 from lldbutil import get_description
304 desc1 = get_description(symbol1)
305 desc2 = get_description(symbol2)
306 self.assertTrue(desc1 and desc2 and desc1 == desc2,
307 "The two addresses should resolve to the same symbol")
Johnny Chend61816b2011-03-03 01:41:57 +0000308
309
310if __name__ == '__main__':
311 import atexit
312 lldb.SBDebugger.Initialize()
313 atexit.register(lambda: lldb.SBDebugger.Terminate())
314 unittest2.main()