1""" 2Test SBTarget APIs. 3""" 4 5import unittest2 6import os 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class TargetAPITestCase(TestBase): 14 15 def setUp(self): 16 # Call super's setUp(). 17 TestBase.setUp(self) 18 # Find the line number to of function 'c'. 19 self.line1 = line_number( 20 'main.c', '// Find the line number for breakpoint 1 here.') 21 self.line2 = line_number( 22 'main.c', '// Find the line number for breakpoint 2 here.') 23 self.line_main = line_number( 24 "main.c", "// Set a break at entry to main.") 25 26 # rdar://problem/9700873 27 # Find global variable value fails for dwarf if inferior not started 28 # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94) 29 # 30 # It does not segfaults now. But for dwarf, the variable value is None if 31 # the inferior process does not exist yet. The radar has been updated. 32 #@unittest232.skip("segmentation fault -- skipping") 33 def test_find_global_variables(self): 34 """Exercise SBTarget.FindGlobalVariables() API.""" 35 d = {'EXE': 'b.out'} 36 self.build(dictionary=d) 37 self.setTearDownCleanup(dictionary=d) 38 self.find_global_variables('b.out') 39 40 def test_find_compile_units(self): 41 """Exercise SBTarget.FindCompileUnits() API.""" 42 d = {'EXE': 'b.out'} 43 self.build(dictionary=d) 44 self.setTearDownCleanup(dictionary=d) 45 self.find_compile_units(self.getBuildArtifact('b.out')) 46 47 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") 48 def test_find_functions(self): 49 """Exercise SBTarget.FindFunctions() API.""" 50 d = {'EXE': 'b.out'} 51 self.build(dictionary=d) 52 self.setTearDownCleanup(dictionary=d) 53 self.find_functions('b.out') 54 55 def test_get_description(self): 56 """Exercise SBTarget.GetDescription() API.""" 57 self.build() 58 self.get_description() 59 60 @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') 61 def test_resolve_symbol_context_with_address(self): 62 """Exercise SBTarget.ResolveSymbolContextForAddress() API.""" 63 self.build() 64 self.resolve_symbol_context_with_address() 65 66 def test_get_platform(self): 67 d = {'EXE': 'b.out'} 68 self.build(dictionary=d) 69 self.setTearDownCleanup(dictionary=d) 70 target = self.create_simple_target('b.out') 71 platform = target.platform 72 self.assertTrue(platform, VALID_PLATFORM) 73 74 def test_get_data_byte_size(self): 75 d = {'EXE': 'b.out'} 76 self.build(dictionary=d) 77 self.setTearDownCleanup(dictionary=d) 78 target = self.create_simple_target('b.out') 79 self.assertEqual(target.data_byte_size, 1) 80 81 def test_get_code_byte_size(self): 82 d = {'EXE': 'b.out'} 83 self.build(dictionary=d) 84 self.setTearDownCleanup(dictionary=d) 85 target = self.create_simple_target('b.out') 86 self.assertEqual(target.code_byte_size, 1) 87 88 def test_resolve_file_address(self): 89 d = {'EXE': 'b.out'} 90 self.build(dictionary=d) 91 self.setTearDownCleanup(dictionary=d) 92 target = self.create_simple_target('b.out') 93 94 # find the file address in the .data section of the main 95 # module 96 data_section = self.find_data_section(target) 97 data_section_addr = data_section.file_addr 98 99 # resolve the above address, and compare the address produced 100 # by the resolution against the original address/section 101 res_file_addr = target.ResolveFileAddress(data_section_addr) 102 self.assertTrue(res_file_addr.IsValid()) 103 104 self.assertEqual(data_section_addr, res_file_addr.file_addr) 105 106 data_section2 = res_file_addr.section 107 self.assertIsNotNone(data_section2) 108 self.assertEqual(data_section.name, data_section2.name) 109 110 def test_get_ABIName(self): 111 d = {'EXE': 'b.out'} 112 self.build(dictionary=d) 113 self.setTearDownCleanup(dictionary=d) 114 target = self.create_simple_target('b.out') 115 116 abi_pre_launch = target.GetABIName() 117 self.assertTrue(len(abi_pre_launch) != 0, "Got an ABI string") 118 119 breakpoint = target.BreakpointCreateByLocation( 120 "main.c", self.line_main) 121 self.assertTrue(breakpoint, VALID_BREAKPOINT) 122 123 # Put debugger into synchronous mode so when we target.LaunchSimple returns 124 # it will guaranteed to be at the breakpoint 125 self.dbg.SetAsync(False) 126 127 # Launch the process, and do not stop at the entry point. 128 process = target.LaunchSimple( 129 None, None, self.get_process_working_directory()) 130 abi_after_launch = target.GetABIName() 131 self.assertEqual(abi_pre_launch, abi_after_launch, "ABI's match before and during run") 132 133 def test_read_memory(self): 134 d = {'EXE': 'b.out'} 135 self.build(dictionary=d) 136 self.setTearDownCleanup(dictionary=d) 137 target = self.create_simple_target('b.out') 138 139 breakpoint = target.BreakpointCreateByLocation( 140 "main.c", self.line_main) 141 self.assertTrue(breakpoint, VALID_BREAKPOINT) 142 143 # Put debugger into synchronous mode so when we target.LaunchSimple returns 144 # it will guaranteed to be at the breakpoint 145 self.dbg.SetAsync(False) 146 147 # Launch the process, and do not stop at the entry point. 148 process = target.LaunchSimple( 149 None, None, self.get_process_working_directory()) 150 151 # find the file address in the .data section of the main 152 # module 153 data_section = self.find_data_section(target) 154 sb_addr = lldb.SBAddress(data_section, 0) 155 error = lldb.SBError() 156 content = target.ReadMemory(sb_addr, 1, error) 157 self.assertSuccess(error, "Make sure memory read succeeded") 158 self.assertEqual(len(content), 1) 159 160 161 @skipIfWindows # stdio manipulation unsupported on Windows 162 @skipIfRemote # stdio manipulation unsupported on remote iOS devices<rdar://problem/54581135> 163 @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) 164 @no_debug_info_test 165 def test_launch_simple(self): 166 d = {'EXE': 'b.out'} 167 self.build(dictionary=d) 168 self.setTearDownCleanup(dictionary=d) 169 target = self.create_simple_target('b.out') 170 171 # Set the debugger to synchronous mode so we only continue after the 172 # process has exited. 173 self.dbg.SetAsync(False) 174 175 process = target.LaunchSimple( 176 ['foo', 'bar'], ['baz'], self.get_process_working_directory()) 177 process.Continue() 178 self.assertState(process.GetState(), lldb.eStateExited) 179 output = process.GetSTDOUT(9999) 180 self.assertIn('arg: foo', output) 181 self.assertIn('arg: bar', output) 182 self.assertIn('env: baz', output) 183 184 self.runCmd("setting set target.run-args foo") 185 self.runCmd("setting set target.env-vars bar=baz") 186 process = target.LaunchSimple(None, None, 187 self.get_process_working_directory()) 188 process.Continue() 189 self.assertState(process.GetState(), lldb.eStateExited) 190 output = process.GetSTDOUT(9999) 191 self.assertIn('arg: foo', output) 192 self.assertIn('env: bar=baz', output) 193 194 # Clear all the run args set above. 195 self.runCmd("setting clear target.run-args") 196 process = target.LaunchSimple(None, None, 197 self.get_process_working_directory()) 198 process.Continue() 199 self.assertEqual(process.GetState(), lldb.eStateExited) 200 output = process.GetSTDOUT(9999) 201 self.assertNotIn('arg: foo', output) 202 203 self.runCmd("settings set target.disable-stdio true") 204 process = target.LaunchSimple( 205 None, None, self.get_process_working_directory()) 206 process.Continue() 207 self.assertState(process.GetState(), lldb.eStateExited) 208 output = process.GetSTDOUT(9999) 209 self.assertEqual(output, "") 210 211 def create_simple_target(self, fn): 212 exe = self.getBuildArtifact(fn) 213 target = self.dbg.CreateTarget(exe) 214 self.assertTrue(target, VALID_TARGET) 215 return target 216 217 def find_data_section(self, target): 218 mod = target.GetModuleAtIndex(0) 219 data_section = None 220 for s in mod.sections: 221 sect_type = s.GetSectionType() 222 if sect_type == lldb.eSectionTypeData: 223 data_section = s 224 break 225 elif sect_type == lldb.eSectionTypeContainer: 226 for i in range(s.GetNumSubSections()): 227 ss = s.GetSubSectionAtIndex(i) 228 sect_type = ss.GetSectionType() 229 if sect_type == lldb.eSectionTypeData: 230 data_section = ss 231 break 232 233 self.assertIsNotNone(data_section) 234 return data_section 235 236 def find_global_variables(self, exe_name): 237 """Exercise SBTarget.FindGlobalVariables() API.""" 238 exe = self.getBuildArtifact(exe_name) 239 240 # Create a target by the debugger. 241 target = self.dbg.CreateTarget(exe) 242 self.assertTrue(target, VALID_TARGET) 243 244 # rdar://problem/9700873 245 # Find global variable value fails for dwarf if inferior not started 246 # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94) 247 # 248 # Remove the lines to create a breakpoint and to start the inferior 249 # which are workarounds for the dwarf case. 250 251 breakpoint = target.BreakpointCreateByLocation('main.c', self.line1) 252 self.assertTrue(breakpoint, VALID_BREAKPOINT) 253 254 # Now launch the process, and do not stop at entry point. 255 process = target.LaunchSimple( 256 None, None, self.get_process_working_directory()) 257 self.assertTrue(process, PROCESS_IS_VALID) 258 # Make sure we hit our breakpoint: 259 thread_list = lldbutil.get_threads_stopped_at_breakpoint( 260 process, breakpoint) 261 self.assertEqual(len(thread_list), 1) 262 263 value_list = target.FindGlobalVariables( 264 'my_global_var_of_char_type', 3) 265 self.assertEqual(value_list.GetSize(), 1) 266 my_global_var = value_list.GetValueAtIndex(0) 267 self.DebugSBValue(my_global_var) 268 self.assertTrue(my_global_var) 269 self.expect(my_global_var.GetName(), exe=False, 270 startstr="my_global_var_of_char_type") 271 self.expect(my_global_var.GetTypeName(), exe=False, 272 startstr="char") 273 self.expect(my_global_var.GetValue(), exe=False, 274 startstr="'X'") 275 276 # While we are at it, let's also exercise the similar 277 # SBModule.FindGlobalVariables() API. 278 for m in target.module_iter(): 279 if os.path.normpath(m.GetFileSpec().GetDirectory()) == self.getBuildDir() and m.GetFileSpec().GetFilename() == exe_name: 280 value_list = m.FindGlobalVariables( 281 target, 'my_global_var_of_char_type', 3) 282 self.assertEqual(value_list.GetSize(), 1) 283 self.assertEqual( 284 value_list.GetValueAtIndex(0).GetValue(), "'X'") 285 break 286 287 def find_compile_units(self, exe): 288 """Exercise SBTarget.FindCompileUnits() API.""" 289 source_name = "main.c" 290 291 # Create a target by the debugger. 292 target = self.dbg.CreateTarget(exe) 293 self.assertTrue(target, VALID_TARGET) 294 295 list = target.FindCompileUnits(lldb.SBFileSpec(source_name, False)) 296 # Executable has been built just from one source file 'main.c', 297 # so we may check only the first element of list. 298 self.assertEqual( 299 list[0].GetCompileUnit().GetFileSpec().GetFilename(), source_name) 300 301 def find_functions(self, exe_name): 302 """Exercise SBTarget.FindFunctions() API.""" 303 exe = self.getBuildArtifact(exe_name) 304 305 # Create a target by the debugger. 306 target = self.dbg.CreateTarget(exe) 307 self.assertTrue(target, VALID_TARGET) 308 309 # Try it with a null name: 310 list = target.FindFunctions(None, lldb.eFunctionNameTypeAuto) 311 self.assertEqual(list.GetSize(), 0) 312 313 list = target.FindFunctions('c', lldb.eFunctionNameTypeAuto) 314 self.assertEqual(list.GetSize(), 1) 315 316 for sc in list: 317 self.assertEqual( 318 sc.GetModule().GetFileSpec().GetFilename(), exe_name) 319 self.assertEqual(sc.GetSymbol().GetName(), 'c') 320 321 def get_description(self): 322 """Exercise SBTarget.GetDescription() API.""" 323 exe = self.getBuildArtifact("a.out") 324 325 # Create a target by the debugger. 326 target = self.dbg.CreateTarget(exe) 327 self.assertTrue(target, VALID_TARGET) 328 329 from lldbsuite.test.lldbutil import get_description 330 331 # get_description() allows no option to mean 332 # lldb.eDescriptionLevelBrief. 333 desc = get_description(target) 334 #desc = get_description(target, option=lldb.eDescriptionLevelBrief) 335 if not desc: 336 self.fail("SBTarget.GetDescription() failed") 337 self.expect(desc, exe=False, 338 substrs=['a.out']) 339 self.expect(desc, exe=False, matching=False, 340 substrs=['Target', 'Module', 'Breakpoint']) 341 342 desc = get_description(target, option=lldb.eDescriptionLevelFull) 343 if not desc: 344 self.fail("SBTarget.GetDescription() failed") 345 self.expect(desc, exe=False, 346 substrs=['Target', 'Module', 'a.out', 'Breakpoint']) 347 348 @skipIfRemote 349 @no_debug_info_test 350 def test_launch_new_process_and_redirect_stdout(self): 351 """Exercise SBTarget.Launch() API with redirected stdout.""" 352 self.build() 353 exe = self.getBuildArtifact("a.out") 354 355 # Create a target by the debugger. 356 target = self.dbg.CreateTarget(exe) 357 self.assertTrue(target, VALID_TARGET) 358 359 # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done. 360 # We should still see the entire stdout redirected once the process is 361 # finished. 362 line = line_number('main.c', '// a(3) -> c(3)') 363 breakpoint = target.BreakpointCreateByLocation('main.c', line) 364 365 # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file. 366 # The inferior should run to completion after "process.Continue()" 367 # call. 368 local_path = self.getBuildArtifact("stdout.txt") 369 if os.path.exists(local_path): 370 os.remove(local_path) 371 372 if lldb.remote_platform: 373 stdout_path = lldbutil.append_to_process_working_directory(self, 374 "lldb-stdout-redirect.txt") 375 else: 376 stdout_path = local_path 377 error = lldb.SBError() 378 process = target.Launch( 379 self.dbg.GetListener(), 380 None, 381 None, 382 None, 383 stdout_path, 384 None, 385 None, 386 0, 387 False, 388 error) 389 process.Continue() 390 #self.runCmd("process status") 391 if lldb.remote_platform: 392 # copy output file to host 393 lldb.remote_platform.Get( 394 lldb.SBFileSpec(stdout_path), 395 lldb.SBFileSpec(local_path)) 396 397 # The 'stdout.txt' file should now exist. 398 self.assertTrue( 399 os.path.isfile(local_path), 400 "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.") 401 402 # Read the output file produced by running the program. 403 with open(local_path, 'r') as f: 404 output = f.read() 405 406 self.expect(output, exe=False, 407 substrs=["a(1)", "b(2)", "a(3)"]) 408 409 def resolve_symbol_context_with_address(self): 410 """Exercise SBTarget.ResolveSymbolContextForAddress() API.""" 411 exe = self.getBuildArtifact("a.out") 412 413 # Create a target by the debugger. 414 target = self.dbg.CreateTarget(exe) 415 self.assertTrue(target, VALID_TARGET) 416 417 # Now create the two breakpoints inside function 'a'. 418 breakpoint1 = target.BreakpointCreateByLocation('main.c', self.line1) 419 breakpoint2 = target.BreakpointCreateByLocation('main.c', self.line2) 420 self.trace("breakpoint1:", breakpoint1) 421 self.trace("breakpoint2:", breakpoint2) 422 self.assertTrue(breakpoint1 and 423 breakpoint1.GetNumLocations() == 1, 424 VALID_BREAKPOINT) 425 self.assertTrue(breakpoint2 and 426 breakpoint2.GetNumLocations() == 1, 427 VALID_BREAKPOINT) 428 429 # Now launch the process, and do not stop at entry point. 430 process = target.LaunchSimple( 431 None, None, self.get_process_working_directory()) 432 self.assertTrue(process, PROCESS_IS_VALID) 433 434 # Frame #0 should be on self.line1. 435 self.assertState(process.GetState(), lldb.eStateStopped) 436 thread = lldbutil.get_stopped_thread( 437 process, lldb.eStopReasonBreakpoint) 438 self.assertTrue( 439 thread.IsValid(), 440 "There should be a thread stopped due to breakpoint condition") 441 #self.runCmd("process status") 442 frame0 = thread.GetFrameAtIndex(0) 443 lineEntry = frame0.GetLineEntry() 444 self.assertEqual(lineEntry.GetLine(), self.line1) 445 446 address1 = lineEntry.GetStartAddress() 447 448 # Continue the inferior, the breakpoint 2 should be hit. 449 process.Continue() 450 self.assertState(process.GetState(), lldb.eStateStopped) 451 thread = lldbutil.get_stopped_thread( 452 process, lldb.eStopReasonBreakpoint) 453 self.assertTrue( 454 thread.IsValid(), 455 "There should be a thread stopped due to breakpoint condition") 456 #self.runCmd("process status") 457 frame0 = thread.GetFrameAtIndex(0) 458 lineEntry = frame0.GetLineEntry() 459 self.assertEqual(lineEntry.GetLine(), self.line2) 460 461 address2 = lineEntry.GetStartAddress() 462 463 self.trace("address1:", address1) 464 self.trace("address2:", address2) 465 466 # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses 467 # from our line entry. 468 context1 = target.ResolveSymbolContextForAddress( 469 address1, lldb.eSymbolContextEverything) 470 context2 = target.ResolveSymbolContextForAddress( 471 address2, lldb.eSymbolContextEverything) 472 473 self.assertTrue(context1 and context2) 474 self.trace("context1:", context1) 475 self.trace("context2:", context2) 476 477 # Verify that the context point to the same function 'a'. 478 symbol1 = context1.GetSymbol() 479 symbol2 = context2.GetSymbol() 480 self.assertTrue(symbol1 and symbol2) 481 self.trace("symbol1:", symbol1) 482 self.trace("symbol2:", symbol2) 483 484 from lldbsuite.test.lldbutil import get_description 485 desc1 = get_description(symbol1) 486 desc2 = get_description(symbol2) 487 self.assertTrue(desc1 and desc2 and desc1 == desc2, 488 "The two addresses should resolve to the same symbol") 489 490 @skipIfRemote 491 def test_default_arch(self): 492 """ Test the other two target create methods using LLDB_ARCH_DEFAULT. """ 493 self.build() 494 exe = self.getBuildArtifact("a.out") 495 target = self.dbg.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT) 496 self.assertTrue(target.IsValid(), "Default arch made a valid target.") 497 # This should also work with the target's triple: 498 target2 = self.dbg.CreateTargetWithFileAndArch(exe, target.GetTriple()) 499 self.assertTrue(target2.IsValid(), "Round trip with triple works") 500 # And this triple should work for the FileAndTriple API: 501 target3 = self.dbg.CreateTargetWithFileAndTargetTriple(exe, target.GetTriple()) 502 self.assertTrue(target3.IsValid()) 503 504 505 @skipIfWindows 506 def test_is_loaded(self): 507 """Exercise SBTarget.IsLoaded(SBModule&) API.""" 508 d = {'EXE': 'b.out'} 509 self.build(dictionary=d) 510 self.setTearDownCleanup(dictionary=d) 511 target = self.create_simple_target('b.out') 512 513 self.assertFalse(target.IsLoaded(lldb.SBModule())) 514 515 num_modules = target.GetNumModules() 516 for i in range(num_modules): 517 module = target.GetModuleAtIndex(i) 518 self.assertFalse(target.IsLoaded(module), "Target that isn't " 519 "running shouldn't have any module loaded.") 520 521 process = target.LaunchSimple(None, None, 522 self.get_process_working_directory()) 523 524 for i in range(num_modules): 525 module = target.GetModuleAtIndex(i) 526 self.assertTrue(target.IsLoaded(module), "Running the target should " 527 "have loaded its modules.") 528