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