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