xref: /llvm-project/lldb/test/API/macosx/find-dsym/deep-bundle/TestDeepBundle.py (revision 80fcecb13c388ff087a27a4b0e7ca3dd8c98eaa4)
1"""Test that a dSYM can be found when a binary is in a deep bundle with multiple pathname components."""
2
3
4from time import sleep
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12exe_name = "deep-bundle"  # must match Makefile
13
14
15class DeepBundleTestCase(TestBase):
16    def setUp(self):
17        TestBase.setUp(self)
18        self.source = "main.c"
19
20    def tearDown(self):
21        # Destroy process before TestBase.tearDown()
22        self.dbg.GetSelectedTarget().GetProcess().Destroy()
23
24        # Call super's tearDown().
25        TestBase.tearDown(self)
26
27    @skipIfRemote
28    @skipUnlessDarwin
29    # This test is explicitly a dSYM test, it doesn't need to run for any other config.
30    @skipIf(debug_info=no_match(["dsym"]))
31    def test_attach_and_check_dsyms(self):
32        """Test attach to binary, see if the framework dSYM is found"""
33        exe = self.getBuildArtifact(exe_name)
34        self.build()
35
36        # Use a file as a synchronization point between test and inferior.
37        pid_file_path = lldbutil.append_to_process_working_directory(
38            self, "token_pid_%d" % (int(os.getpid()))
39        )
40        self.addTearDownHook(
41            lambda: self.run_platform_command("rm %s" % (pid_file_path))
42        )
43
44        popen = self.spawnSubprocess(exe, [self.getBuildDir(), pid_file_path])
45
46        # Wait for the inferior to start up, dlopen a bundle, remove the bundle it linked in
47        pid = lldbutil.wait_for_file_on_target(self, pid_file_path)
48
49        # Since the library that was dlopen()'ed is now removed, lldb will need to find the
50        # binary & dSYM via target.exec-search-paths
51        settings_str = (
52            "settings set target.exec-search-paths "
53            + self.get_process_working_directory()
54            + "/hide.app"
55        )
56        self.runCmd(settings_str)
57        self.runCmd("process attach -p " + str(popen.pid))
58
59        target = self.dbg.GetSelectedTarget()
60        self.assertTrue(
61            target.IsValid(), "Should have a valid Target after attaching to process"
62        )
63
64        setup_complete = target.FindFirstGlobalVariable("setup_is_complete")
65        self.assertEqual(
66            setup_complete.GetValueAsUnsigned(),
67            1,
68            "Check that inferior process has completed setup",
69        )
70
71        # Find the bundle module, see if we found the dSYM too (they're both in "hide.app")
72        i = 0
73        found_module = False
74        while i < target.GetNumModules():
75            mod = target.GetModuleAtIndex(i)
76            if mod.GetFileSpec().GetFilename() == "MyFramework":
77                found_module = True
78                dsym_name = mod.GetSymbolFileSpec().GetFilename()
79                self.assertEqual(
80                    dsym_name,
81                    "MyFramework",
82                    "Check that we found the dSYM for the bundle that was loaded",
83                )
84            i = i + 1
85
86        self.assertTrue(
87            found_module,
88            "Check that we found the framework loaded in lldb's image list",
89        )
90