xref: /llvm-project/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py (revision 1988c27e5f4dbcf42c9a80f44bdee7ccd208a0ac)
1"""Test that we don't read objc class tables early in process startup."""
2
3import time
4import lldb
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import *
7from lldbsuite.test import lldbutil
8
9
10class TestEarlyProcessLaunch(TestBase):
11    NO_DEBUG_INFO_TESTCASE = True
12
13    @skipUnlessDarwin
14    @skipIfAsan  # rdar://103359354
15    @skipIfOutOfTreeDebugserver  # 2022-12-13 FIXME: skipping system debugserver
16    # until this feature is included in the system
17    # debugserver.
18    @add_test_categories(["pyapi"])
19    def test_early_process_launch(self):
20        """Test that we don't read objc class tables early in proc startup"""
21        self.build()
22
23        ###
24        ### Hit a breakpoint on the first malloc() call, which
25        ### is before libSystem has finished initializing.  At
26        ### this point, we should not read the objc class tables.
27        ### Then continue to main(), which is past libSystem
28        ### initializing.  Try again, and they should be read.
29        ###
30        ### Use the types logging to detect the difference.
31
32        exe = self.getBuildArtifact("a.out")
33        target = self.dbg.CreateTarget(exe)
34        self.assertTrue(target.IsValid())
35        bkpt = target.BreakpointCreateByRegex("alloc", None)
36        self.assertTrue(bkpt.IsValid())
37        (target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(
38            self, target, bkpt
39        )
40
41        target.DisableAllBreakpoints()
42        target.BreakpointCreateByName("main")
43
44        logfile_early = os.path.join(self.getBuildDir(), "types-log-early.txt")
45        self.addTearDownHook(lambda: self.runCmd("log disable lldb types"))
46        self.runCmd("log enable -f %s lldb types" % logfile_early)
47        self.runCmd("expression --language objc -- global = 15")
48
49        err = process.Continue()
50        self.assertTrue(err.Success())
51
52        logfile_later = os.path.join(self.getBuildDir(), "types-log-later.txt")
53        self.runCmd("log enable -f %s lldb types" % logfile_later)
54        self.runCmd("expression --language objc -- global = 25")
55
56        self.assertTrue(os.path.exists(logfile_early))
57        self.assertTrue(os.path.exists(logfile_later))
58        early_text = open(logfile_early).read()
59        later_text = open(logfile_later).read()
60
61        self.assertIn("ran: no, retry: yes", early_text)
62        self.assertNotIn("ran: no, retry: yes", later_text)
63
64        self.assertNotIn("ran: yes, retry: no", early_text)
65        self.assertIn("ran: yes, retry: no", later_text)
66