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