7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class TargetAPITestCase(TestBase
):
14 # Call super's setUp().
16 # Find the line number to of function 'c'.
17 self
.line1
= line_number(
18 "main.c", "// Find the line number for breakpoint 1 here."
20 self
.line2
= line_number(
21 "main.c", "// Find the line number for breakpoint 2 here."
23 self
.line_main
= line_number("main.c", "// Set a break at entry to main.")
25 # rdar://problem/9700873
26 # 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)
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 def test_find_global_variables(self
):
32 """Exercise SBTarget.FindGlobalVariables() API."""
34 self
.build(dictionary
=d
)
35 self
.setTearDownCleanup(dictionary
=d
)
36 self
.find_global_variables("b.out")
38 def test_find_compile_units(self
):
39 """Exercise SBTarget.FindCompileUnits() API."""
41 self
.build(dictionary
=d
)
42 self
.setTearDownCleanup(dictionary
=d
)
43 self
.find_compile_units(self
.getBuildArtifact("b.out"))
45 @expectedFailureAll(oslist
=["windows"], bugnumber
="llvm.org/pr24778")
46 def test_find_functions(self
):
47 """Exercise SBTarget.FindFunctions() API."""
49 self
.build(dictionary
=d
)
50 self
.setTearDownCleanup(dictionary
=d
)
51 self
.find_functions("b.out")
53 def test_get_description(self
):
54 """Exercise SBTarget.GetDescription() API."""
56 self
.get_description()
58 @expectedFailureAll(oslist
=["windows"], bugnumber
="llvm.org/pr21765")
59 def test_resolve_symbol_context_with_address(self
):
60 """Exercise SBTarget.ResolveSymbolContextForAddress() API."""
62 self
.resolve_symbol_context_with_address()
64 def test_get_platform(self
):
66 self
.build(dictionary
=d
)
67 self
.setTearDownCleanup(dictionary
=d
)
68 target
= self
.create_simple_target("b.out")
69 platform
= target
.platform
70 self
.assertTrue(platform
, VALID_PLATFORM
)
72 def test_get_data_byte_size(self
):
74 self
.build(dictionary
=d
)
75 self
.setTearDownCleanup(dictionary
=d
)
76 target
= self
.create_simple_target("b.out")
77 self
.assertEqual(target
.data_byte_size
, 1)
79 def test_get_code_byte_size(self
):
81 self
.build(dictionary
=d
)
82 self
.setTearDownCleanup(dictionary
=d
)
83 target
= self
.create_simple_target("b.out")
84 self
.assertEqual(target
.code_byte_size
, 1)
86 def test_resolve_file_address(self
):
88 self
.build(dictionary
=d
)
89 self
.setTearDownCleanup(dictionary
=d
)
90 target
= self
.create_simple_target("b.out")
92 # find the file address in the .data section of the main
94 data_section
= self
.find_data_section(target
)
95 data_section_addr
= data_section
.file_addr
97 # resolve the above address, and compare the address produced
98 # by the resolution against the original address/section
99 res_file_addr
= target
.ResolveFileAddress(data_section_addr
)
100 self
.assertTrue(res_file_addr
.IsValid())
102 self
.assertEqual(data_section_addr
, res_file_addr
.file_addr
)
104 data_section2
= res_file_addr
.section
105 self
.assertIsNotNone(data_section2
)
106 self
.assertEqual(data_section
.name
, data_section2
.name
)
108 def test_get_ABIName(self
):
110 self
.build(dictionary
=d
)
111 self
.setTearDownCleanup(dictionary
=d
)
112 target
= self
.create_simple_target("b.out")
114 abi_pre_launch
= target
.GetABIName()
115 self
.assertNotEqual(len(abi_pre_launch
), 0, "Got an ABI string")
117 breakpoint
= target
.BreakpointCreateByLocation("main.c", self
.line_main
)
118 self
.assertTrue(breakpoint
, VALID_BREAKPOINT
)
120 # Put debugger into synchronous mode so when we target.LaunchSimple returns
121 # it will guaranteed to be at the breakpoint
122 self
.dbg
.SetAsync(False)
124 # Launch the process, and do not stop at the entry point.
125 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
126 abi_after_launch
= target
.GetABIName()
128 abi_pre_launch
, abi_after_launch
, "ABI's match before and during run"
131 def test_read_memory(self
):
133 self
.build(dictionary
=d
)
134 self
.setTearDownCleanup(dictionary
=d
)
135 target
= self
.create_simple_target("b.out")
137 breakpoint
= target
.BreakpointCreateByLocation("main.c", self
.line_main
)
138 self
.assertTrue(breakpoint
, VALID_BREAKPOINT
)
140 # Put debugger into synchronous mode so when we target.LaunchSimple returns
141 # it will guaranteed to be at the breakpoint
142 self
.dbg
.SetAsync(False)
144 # Launch the process, and do not stop at the entry point.
145 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
147 # find the file address in the .data section of the main
149 data_section
= self
.find_data_section(target
)
150 sb_addr
= lldb
.SBAddress(data_section
, 0)
151 error
= lldb
.SBError()
152 content
= target
.ReadMemory(sb_addr
, 1, error
)
153 self
.assertSuccess(error
, "Make sure memory read succeeded")
154 self
.assertEqual(len(content
), 1)
156 @skipIfWindows # stdio manipulation unsupported on Windows
157 @skipIfRemote # stdio manipulation unsupported on remote iOS devices<rdar://problem/54581135>
158 @skipIf(oslist
=["linux"], archs
=["arm", "aarch64"])
160 def test_launch_simple(self
):
162 self
.build(dictionary
=d
)
163 self
.setTearDownCleanup(dictionary
=d
)
164 target
= self
.create_simple_target("b.out")
166 # Set the debugger to synchronous mode so we only continue after the
167 # process has exited.
168 self
.dbg
.SetAsync(False)
170 process
= target
.LaunchSimple(
171 ["foo", "bar"], ["baz"], self
.get_process_working_directory()
174 self
.assertState(process
.GetState(), lldb
.eStateExited
)
175 output
= process
.GetSTDOUT(9999)
176 self
.assertIn("arg: foo", output
)
177 self
.assertIn("arg: bar", output
)
178 self
.assertIn("env: baz", output
)
180 self
.runCmd("setting set target.run-args foo")
181 self
.runCmd("setting set target.env-vars bar=baz")
182 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
184 self
.assertState(process
.GetState(), lldb
.eStateExited
)
185 output
= process
.GetSTDOUT(9999)
186 self
.assertIn("arg: foo", output
)
187 self
.assertIn("env: bar=baz", output
)
189 # Clear all the run args set above.
190 self
.runCmd("setting clear target.run-args")
191 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
193 self
.assertEqual(process
.GetState(), lldb
.eStateExited
)
194 output
= process
.GetSTDOUT(9999)
195 self
.assertNotIn("arg: foo", output
)
197 self
.runCmd("settings set target.disable-stdio true")
198 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
200 self
.assertState(process
.GetState(), lldb
.eStateExited
)
201 output
= process
.GetSTDOUT(9999)
202 self
.assertEqual(output
, "")
204 def create_simple_target(self
, fn
):
205 exe
= self
.getBuildArtifact(fn
)
206 target
= self
.dbg
.CreateTarget(exe
)
207 self
.assertTrue(target
, VALID_TARGET
)
210 def find_data_section(self
, target
):
211 mod
= target
.GetModuleAtIndex(0)
213 for s
in mod
.sections
:
214 sect_type
= s
.GetSectionType()
215 if sect_type
== lldb
.eSectionTypeData
:
218 elif sect_type
== lldb
.eSectionTypeContainer
:
219 for i
in range(s
.GetNumSubSections()):
220 ss
= s
.GetSubSectionAtIndex(i
)
221 sect_type
= ss
.GetSectionType()
222 if sect_type
== lldb
.eSectionTypeData
:
226 self
.assertIsNotNone(data_section
)
229 def find_global_variables(self
, exe_name
):
230 """Exercise SBTarget.FindGlobalVariables() API."""
231 exe
= self
.getBuildArtifact(exe_name
)
233 # Create a target by the debugger.
234 target
= self
.dbg
.CreateTarget(exe
)
235 self
.assertTrue(target
, VALID_TARGET
)
237 # rdar://problem/9700873
238 # Find global variable value fails for dwarf if inferior not started
239 # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94)
241 # Remove the lines to create a breakpoint and to start the inferior
242 # which are workarounds for the dwarf case.
244 breakpoint
= target
.BreakpointCreateByLocation("main.c", self
.line1
)
245 self
.assertTrue(breakpoint
, VALID_BREAKPOINT
)
247 # Now launch the process, and do not stop at entry point.
248 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
249 self
.assertTrue(process
, PROCESS_IS_VALID
)
250 # Make sure we hit our breakpoint:
251 thread_list
= lldbutil
.get_threads_stopped_at_breakpoint(process
, breakpoint
)
252 self
.assertEqual(len(thread_list
), 1)
254 value_list
= target
.FindGlobalVariables("my_global_var_of_char_type", 3)
255 self
.assertEqual(value_list
.GetSize(), 1)
256 my_global_var
= value_list
.GetValueAtIndex(0)
257 self
.DebugSBValue(my_global_var
)
258 self
.assertTrue(my_global_var
)
260 my_global_var
.GetName(), exe
=False, startstr
="my_global_var_of_char_type"
262 self
.expect(my_global_var
.GetTypeName(), exe
=False, startstr
="char")
263 self
.expect(my_global_var
.GetValue(), exe
=False, startstr
="'X'")
265 # While we are at it, let's also exercise the similar
266 # SBModule.FindGlobalVariables() API.
267 for m
in target
.module_iter():
269 os
.path
.normpath(m
.GetFileSpec().GetDirectory()) == self
.getBuildDir()
270 and m
.GetFileSpec().GetFilename() == exe_name
272 value_list
= m
.FindGlobalVariables(
273 target
, "my_global_var_of_char_type", 3
275 self
.assertEqual(value_list
.GetSize(), 1)
276 self
.assertEqual(value_list
.GetValueAtIndex(0).GetValue(), "'X'")
279 def find_compile_units(self
, exe
):
280 """Exercise SBTarget.FindCompileUnits() API."""
281 source_name
= "main.c"
283 # Create a target by the debugger.
284 target
= self
.dbg
.CreateTarget(exe
)
285 self
.assertTrue(target
, VALID_TARGET
)
287 list = target
.FindCompileUnits(lldb
.SBFileSpec(source_name
, False))
288 # Executable has been built just from one source file 'main.c',
289 # so we may check only the first element of list.
291 list[0].GetCompileUnit().GetFileSpec().GetFilename(), source_name
294 def find_functions(self
, exe_name
):
295 """Exercise SBTarget.FindFunctions() API."""
296 exe
= self
.getBuildArtifact(exe_name
)
298 # Create a target by the debugger.
299 target
= self
.dbg
.CreateTarget(exe
)
300 self
.assertTrue(target
, VALID_TARGET
)
302 # Try it with a null name:
303 list = target
.FindFunctions(None, lldb
.eFunctionNameTypeAuto
)
304 self
.assertEqual(list.GetSize(), 0)
306 list = target
.FindFunctions("c", lldb
.eFunctionNameTypeAuto
)
307 self
.assertEqual(list.GetSize(), 1)
310 self
.assertEqual(sc
.GetModule().GetFileSpec().GetFilename(), exe_name
)
311 self
.assertEqual(sc
.GetSymbol().GetName(), "c")
313 def get_description(self
):
314 """Exercise SBTarget.GetDescription() API."""
315 exe
= self
.getBuildArtifact("a.out")
317 # Create a target by the debugger.
318 target
= self
.dbg
.CreateTarget(exe
)
319 self
.assertTrue(target
, VALID_TARGET
)
321 from lldbsuite
.test
.lldbutil
import get_description
323 # get_description() allows no option to mean
324 # lldb.eDescriptionLevelBrief.
325 desc
= get_description(target
)
326 # desc = get_description(target, option=lldb.eDescriptionLevelBrief)
328 self
.fail("SBTarget.GetDescription() failed")
329 self
.expect(desc
, exe
=False, substrs
=["a.out"])
331 desc
, exe
=False, matching
=False, substrs
=["Target", "Module", "Breakpoint"]
334 desc
= get_description(target
, option
=lldb
.eDescriptionLevelFull
)
336 self
.fail("SBTarget.GetDescription() failed")
338 desc
, exe
=False, substrs
=["Target", "Module", "a.out", "Breakpoint"]
343 def test_launch_new_process_and_redirect_stdout(self
):
344 """Exercise SBTarget.Launch() API with redirected stdout."""
346 exe
= self
.getBuildArtifact("a.out")
348 # Create a target by the debugger.
349 target
= self
.dbg
.CreateTarget(exe
)
350 self
.assertTrue(target
, VALID_TARGET
)
352 # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done.
353 # We should still see the entire stdout redirected once the process is
355 line
= line_number("main.c", "// a(3) -> c(3)")
356 breakpoint
= target
.BreakpointCreateByLocation("main.c", line
)
358 # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file.
359 # The inferior should run to completion after "process.Continue()"
361 local_path
= self
.getBuildArtifact("stdout.txt")
362 if os
.path
.exists(local_path
):
363 os
.remove(local_path
)
365 if lldb
.remote_platform
:
366 stdout_path
= lldbutil
.append_to_process_working_directory(
367 self
, "lldb-stdout-redirect.txt"
370 stdout_path
= local_path
371 error
= lldb
.SBError()
372 process
= target
.Launch(
373 self
.dbg
.GetListener(),
385 # self.runCmd("process status")
386 if lldb
.remote_platform
:
387 # copy output file to host
388 lldb
.remote_platform
.Get(
389 lldb
.SBFileSpec(stdout_path
), lldb
.SBFileSpec(local_path
)
392 # The 'stdout.txt' file should now exist.
394 os
.path
.isfile(local_path
),
395 "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.",
398 # Read the output file produced by running the program.
399 with
open(local_path
, "r") as f
:
402 self
.expect(output
, exe
=False, substrs
=["a(1)", "b(2)", "a(3)"])
404 def resolve_symbol_context_with_address(self
):
405 """Exercise SBTarget.ResolveSymbolContextForAddress() API."""
406 exe
= self
.getBuildArtifact("a.out")
408 # Create a target by the debugger.
409 target
= self
.dbg
.CreateTarget(exe
)
410 self
.assertTrue(target
, VALID_TARGET
)
412 # Now create the two breakpoints inside function 'a'.
413 breakpoint1
= target
.BreakpointCreateByLocation("main.c", self
.line1
)
414 breakpoint2
= target
.BreakpointCreateByLocation("main.c", self
.line2
)
415 self
.trace("breakpoint1:", breakpoint1
)
416 self
.trace("breakpoint2:", breakpoint2
)
418 breakpoint1
and breakpoint1
.GetNumLocations() == 1, VALID_BREAKPOINT
421 breakpoint2
and breakpoint2
.GetNumLocations() == 1, VALID_BREAKPOINT
424 # Now launch the process, and do not stop at entry point.
425 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
426 self
.assertTrue(process
, PROCESS_IS_VALID
)
428 # Frame #0 should be on self.line1.
429 self
.assertState(process
.GetState(), lldb
.eStateStopped
)
430 thread
= lldbutil
.get_stopped_thread(process
, lldb
.eStopReasonBreakpoint
)
433 "There should be a thread stopped due to breakpoint condition",
435 # self.runCmd("process status")
436 frame0
= thread
.GetFrameAtIndex(0)
437 lineEntry
= frame0
.GetLineEntry()
438 self
.assertEqual(lineEntry
.GetLine(), self
.line1
)
440 address1
= lineEntry
.GetStartAddress()
442 # Continue the inferior, the breakpoint 2 should be hit.
444 self
.assertState(process
.GetState(), lldb
.eStateStopped
)
445 thread
= lldbutil
.get_stopped_thread(process
, lldb
.eStopReasonBreakpoint
)
448 "There should be a thread stopped due to breakpoint condition",
450 # self.runCmd("process status")
451 frame0
= thread
.GetFrameAtIndex(0)
452 lineEntry
= frame0
.GetLineEntry()
453 self
.assertEqual(lineEntry
.GetLine(), self
.line2
)
455 address2
= lineEntry
.GetStartAddress()
457 self
.trace("address1:", address1
)
458 self
.trace("address2:", address2
)
460 # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses
461 # from our line entry.
462 context1
= target
.ResolveSymbolContextForAddress(
463 address1
, lldb
.eSymbolContextEverything
465 context2
= target
.ResolveSymbolContextForAddress(
466 address2
, lldb
.eSymbolContextEverything
469 self
.assertTrue(context1
and context2
)
470 self
.trace("context1:", context1
)
471 self
.trace("context2:", context2
)
473 # Verify that the context point to the same function 'a'.
474 symbol1
= context1
.GetSymbol()
475 symbol2
= context2
.GetSymbol()
476 self
.assertTrue(symbol1
and symbol2
)
477 self
.trace("symbol1:", symbol1
)
478 self
.trace("symbol2:", symbol2
)
480 from lldbsuite
.test
.lldbutil
import get_description
482 desc1
= get_description(symbol1
)
483 desc2
= get_description(symbol2
)
485 desc1
and desc2
and desc1
== desc2
,
486 "The two addresses should resolve to the same symbol",
490 def test_default_arch(self
):
491 """Test the other two target create methods using LLDB_ARCH_DEFAULT."""
493 exe
= self
.getBuildArtifact("a.out")
494 target
= self
.dbg
.CreateTargetWithFileAndArch(exe
, lldb
.LLDB_ARCH_DEFAULT
)
495 self
.assertTrue(target
.IsValid(), "Default arch made a valid target.")
496 # This should also work with the target's triple:
497 target2
= self
.dbg
.CreateTargetWithFileAndArch(exe
, target
.GetTriple())
498 self
.assertTrue(target2
.IsValid(), "Round trip with triple works")
499 # And this triple should work for the FileAndTriple API:
500 target3
= self
.dbg
.CreateTargetWithFileAndTargetTriple(exe
, target
.GetTriple())
501 self
.assertTrue(target3
.IsValid())
504 def test_is_loaded(self
):
505 """Exercise SBTarget.IsLoaded(SBModule&) API."""
507 self
.build(dictionary
=d
)
508 self
.setTearDownCleanup(dictionary
=d
)
509 target
= self
.create_simple_target("b.out")
511 self
.assertFalse(target
.IsLoaded(lldb
.SBModule()))
513 num_modules
= target
.GetNumModules()
514 for i
in range(num_modules
):
515 module
= target
.GetModuleAtIndex(i
)
517 target
.IsLoaded(module
),
518 "Target that isn't " "running shouldn't have any module loaded.",
521 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
523 for i
in range(num_modules
):
524 module
= target
.GetModuleAtIndex(i
)
526 target
.IsLoaded(module
),
527 "Running the target should " "have loaded its modules.",
531 def test_setting_selected_target_with_invalid_target(self
):
532 """Make sure we don't crash when trying to select invalid target."""
533 target
= lldb
.SBTarget()
534 self
.dbg
.SetSelectedTarget(target
)