1import lldb 2from lldbsuite.test.decorators import * 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test import lldbutil 5 6class TestCase(TestBase): 7 8 mydir = TestBase.compute_mydir(__file__) 9 NO_DEBUG_INFO_TESTCASE = True 10 11 @skipIfRemote 12 def test_load_after_attach(self): 13 self.build() 14 15 ctx = self.platformContext 16 lib_name = ctx.shlib_prefix + 'lib_b.' + ctx.shlib_extension 17 18 exe = self.getBuildArtifact("a.out") 19 lib = self.getBuildArtifact(lib_name) 20 21 target = self.dbg.CreateTarget(exe) 22 environment = self.registerSharedLibrariesWithTarget(target, ["lib_b"]) 23 24 # Spawn a new process. 25 # use realpath to workaround llvm.org/pr48376 26 # Pass path to solib for dlopen to properly locate the library. 27 popen = self.spawnSubprocess(os.path.realpath(exe), extra_env=environment) 28 29 # Attach to the spawned process. 30 error = lldb.SBError() 31 process = target.AttachToProcessWithID(self.dbg.GetListener(), 32 popen.pid, error) 33 self.assertSuccess(error) 34 35 # Continue until first breakpoint. 36 breakpoint1 = self.target().BreakpointCreateBySourceRegex( 37 "// break here", lldb.SBFileSpec("main.cpp")) 38 self.assertEqual(breakpoint1.GetNumResolvedLocations(), 1) 39 stopped_threads = lldbutil.continue_to_breakpoint(self.process(), breakpoint1) 40 self.assertEqual(len(stopped_threads), 1) 41 42 # Change a variable to escape the loop 43 self.runCmd("expression main_thread_continue = 1") 44 45 # Continue so that dlopen is called. 46 breakpoint2 = self.target().BreakpointCreateBySourceRegex( 47 "// break after dlopen", lldb.SBFileSpec("main.cpp")) 48 self.assertEqual(breakpoint2.GetNumResolvedLocations(), 1) 49 stopped_threads = lldbutil.continue_to_breakpoint(self.process(), breakpoint2) 50 self.assertEqual(len(stopped_threads), 1) 51 52 # Check that image list contains liblib_b after dlopen. 53 self.match( 54 "image list", 55 patterns = [lib_name], 56 matching = True, 57 msg = lib_name + " missing in image list") 58 59