This relands https://github.com/llvm/llvm-project/pull/95963. It had to be reverted because the `TestEarlyProcessLaunch.py` test was failing on the incremental macOS bots. The test failed because it was relying on expression log output from the ObjC introspection routines (but was the expression was called from a C++ context). The relanded patch simply ensures that the test runs the expressions as `ObjC` expressions. When LLDB isn't able to find a `clang::Decl` in response to a `FindExternalVisibleDeclsByName`, it will fall-back to looking into the Objective-C runtime for that decl. This ends up doing a lot of work which isn't necessary when we're debugging a C++ program. This patch makes the ObjC lookup conditional on the language that the ExpressionParser deduced (which can be explicitly set using the `expr --language` option or is set implicitly if we're stopped in an ObjC frame or a C++ frame without debug-info). rdar://96236519
60 lines
2.2 KiB
Python
60 lines
2.2 KiB
Python
"""Test that we don't read objc class tables early in process startup."""
|
|
|
|
|
|
import time
|
|
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
|
|
class TestEarlyProcessLaunch(TestBase):
|
|
NO_DEBUG_INFO_TESTCASE = True
|
|
|
|
@skipUnlessDarwin
|
|
@skipIfAsan # rdar://103359354
|
|
@skipIfOutOfTreeDebugserver # 2022-12-13 FIXME: skipping system debugserver
|
|
# until this feature is included in the system
|
|
# debugserver.
|
|
@add_test_categories(["pyapi"])
|
|
def test_early_process_launch(self):
|
|
"""Test that we don't read objc class tables early in proc startup"""
|
|
self.build()
|
|
|
|
###
|
|
### Hit a breakpoint on the first malloc() call, which
|
|
### is before libSystem has finished initializing. At
|
|
### this point, we should not read the objc class tables.
|
|
### Then continue to main(), which is past libSystem
|
|
### initializing. Try again, and they should be read.
|
|
###
|
|
### Use the types logging to detect the difference.
|
|
|
|
target, process, _, bkpt = lldbutil.run_to_name_breakpoint(self, "malloc")
|
|
|
|
target.DisableAllBreakpoints()
|
|
target.BreakpointCreateByName("main")
|
|
|
|
logfile_early = os.path.join(self.getBuildDir(), "types-log-early.txt")
|
|
self.addTearDownHook(lambda: self.runCmd("log disable lldb types"))
|
|
self.runCmd("log enable -f %s lldb types" % logfile_early)
|
|
self.runCmd("expression --language objc -- global = 15")
|
|
|
|
err = process.Continue()
|
|
self.assertTrue(err.Success())
|
|
|
|
logfile_later = os.path.join(self.getBuildDir(), "types-log-later.txt")
|
|
self.runCmd("log enable -f %s lldb types" % logfile_later)
|
|
self.runCmd("expression --language objc -- global = 25")
|
|
|
|
self.assertTrue(os.path.exists(logfile_early))
|
|
self.assertTrue(os.path.exists(logfile_later))
|
|
early_text = open(logfile_early).read()
|
|
later_text = open(logfile_later).read()
|
|
|
|
self.assertIn("ran: no, retry: yes", early_text)
|
|
self.assertNotIn("ran: no, retry: yes", later_text)
|
|
|
|
self.assertNotIn("ran: yes, retry: no", early_text)
|
|
self.assertIn("ran: yes, retry: no", later_text)
|