Author: Raphael Isemann Date: 2026-06-17T08:46:03Z New Revision: b59f9651cecfe0f3a33035846b991a9968ee26c5
URL: https://github.com/llvm/llvm-project/commit/b59f9651cecfe0f3a33035846b991a9968ee26c5 DIFF: https://github.com/llvm/llvm-project/commit/b59f9651cecfe0f3a33035846b991a9968ee26c5.diff LOG: [lldb][test] Cleanup and modernize TestHiddenIvars.py (#202023) This is simple rewrite of the test. The patch improves three things: * It replaces old expect tests with the new expect_* variants that no longer rely on substring matching. * It unifies the strip/non-stripped checks as we actually produce identical SBValues in both cases (by fetching data from the Objective-C runtime). * It builds this test with a shared build directory. Our stripping logic generates a new stripped binary in a subdirectory and doesn't touch the shared build files. This also halves the test runtime to 6s. Added: Modified: lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py Removed: ################################################################################ diff --git a/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py b/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py index d21b427c54ffc..d2ed2f1130437 100644 --- a/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py +++ b/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py @@ -1,8 +1,7 @@ """Test that hidden ivars in a shared library are visible from the main executable.""" -import subprocess - import unittest + import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -10,224 +9,117 @@ @skipIfTargetDoesNotSupportSharedLibraries() +@skipIf(archs=["i386"]) # requires modern objc runtime class HiddenIvarsTestCase(TestBase): - SHARED_BUILD_TESTCASE = False - - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break inside main(). - self.source = "main.m" - self.line = line_number(self.source, "// breakpoint1") - # The makefile names of the shared libraries as they appear in DYLIB_NAME. - # The names should have no loading "lib" or extension as they will be - # localized - self.shlib_names = ["InternalDefiner"] + SHARED_BUILD_TESTCASE = True + + def common_setup(self, strip): + exe_name = "stripped/a.out" if strip else "a.out" + return lldbutil.run_to_source_breakpoint( + self, + "// breakpoint1", + lldb.SBFileSpec("main.m"), + exe_name=exe_name, + extra_images=["InternalDefiner"], + ) @skipIf( debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM", ) def test_expr_stripped(self): - if self.getArchitecture() == "i386": - self.skipTest("requires modern objc runtime") - else: - self.build() - self.expr(True) + self.build() + self.expr(strip=True) def test_expr(self): - if self.getArchitecture() == "i386": - self.skipTest("requires modern objc runtime") - else: - self.build() - self.expr(False) + self.build() + self.expr(strip=False) @skipIf( debug_info=no_match("dsym"), bugnumber="This test requires a stripped binary and a dSYM", ) def test_frame_variable_stripped(self): - if self.getArchitecture() == "i386": - self.skipTest("requires modern objc runtime") - else: - self.build() - self.frame_var(True) + self.build() + self.frame_var(strip=True) def test_frame_variable(self): - if self.getArchitecture() == "i386": - self.skipTest("requires modern objc runtime") - else: - self.build() - self.frame_var(False) + self.build() + self.frame_var(strip=False) @unittest.expectedFailure # rdar://18683637 def test_frame_variable_across_modules(self): - if self.getArchitecture() == "i386": - self.skipTest("requires modern objc runtime") - else: - self.build() - self.common_setup(False) - self.expect( - "frame variable k->bar", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 3"] - ) - - def common_setup(self, strip): - if strip: - exe = self.getBuildArtifact("stripped/a.out") - else: - exe = self.getBuildArtifact("a.out") - # Create a target by the debugger. - target = self.dbg.CreateTarget(exe) - self.assertTrue(target, VALID_TARGET) - - # Create the breakpoint inside function 'main'. - breakpoint = target.BreakpointCreateByLocation(self.source, self.line) - self.assertTrue(breakpoint, VALID_BREAKPOINT) - - # Register our shared libraries for remote targets so they get - # automatically uploaded - environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names) - - # Now launch the process, and do not stop at entry point. - process = target.LaunchSimple( - None, environment, self.get_process_working_directory() - ) - self.assertTrue(process, PROCESS_IS_VALID) - - self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - - # Break inside the foo function which takes a bar_ptr argument. - lldbutil.run_break_set_by_file_and_line( - self, "main.m", self.line, num_expected_locations=1, loc_exact=True - ) - - self.runCmd("run", RUN_SUCCEEDED) - - # The stop reason of the thread should be breakpoint. - self.expect( - "thread list", - STOPPED_DUE_TO_BREAKPOINT, - substrs=["stopped", "stop reason = breakpoint"], - ) - - # The breakpoint should have a hit count of 1. - lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1) + self.build() + self.common_setup(False) + self.expect_var_path("k->bar", value="3") def expr(self, strip): self.common_setup(strip) - # This should display correctly. - self.expect( - "expression (j->_definer->foo)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["= 4"], - ) - - self.expect( - "expression (j->_definer->bar)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["= 5"], - ) - - if strip: - self.expect( - "expression *(j->_definer)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 4"], - ) - else: - self.expect( - "expression *(j->_definer)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 4", "bar = 5"], - ) - - self.expect( - "expression (k->foo)", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 2"] - ) - - self.expect( - "expression (k->bar)", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 3"] + self.expect_expr("j->_definer->foo", result_value="4") + self.expect_expr("j->_definer->bar", result_value="5") + + self.expect_expr( + "*(j->_definer)", + result_type="InternalDefiner", + result_children=[ + ValueCheck(name="NSObject"), + ValueCheck(name="foo", value="4"), + ValueCheck(name="bar", value="5"), + ], ) - self.expect( - "expression k.filteredDataSource", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[" = 0x", '"2 elements"'], + self.expect_expr("k->foo", result_value="2") + self.expect_expr("k->bar", result_value="3") + + self.expect_expr("k.filteredDataSource", result_summary='@"2 elements"') + + self.expect_expr( + "*k", + result_type="InheritContainer", + result_children=[ + ValueCheck( + name="InternalDefiner", + children=[ + ValueCheck(name="NSObject"), + ValueCheck(name="foo", value="2"), + ValueCheck(name="bar", value="3"), + ], + ), + ValueCheck(name="_filteredDataSource", summary='@"2 elements"'), + ], ) - if strip: - self.expect( - "expression *(k)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 2", " = 0x", '"2 elements"'], - ) - else: - self.expect( - "expression *(k)", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - "foo = 2", - "bar = 3", - "_filteredDataSource = 0x", - '"2 elements"', - ], - ) - def frame_var(self, strip): self.common_setup(strip) - # This should display correctly. - self.expect( - "frame variable j->_definer->foo", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["= 4"], - ) + self.expect_var_path("j->_definer->foo", value="4") + self.expect_var_path("j->_definer->bar", value="5") - if not strip: - self.expect( - "frame variable j->_definer->bar", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["= 5"], - ) - - if strip: - self.expect( - "frame variable *j->_definer", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 4"], - ) - else: - self.expect( - "frame variable *j->_definer", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 4", "bar = 5"], - ) - - self.expect( - "frame variable k->foo", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 2"] + self.expect_var_path( + "*j->_definer", + children=[ + ValueCheck(name="NSObject"), + ValueCheck(name="foo", value="4"), + ValueCheck(name="bar", value="5"), + ], ) - self.expect( - "frame variable k->_filteredDataSource", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[" = 0x", '"2 elements"'], + self.expect_var_path("k->foo", value="2") + self.expect_var_path("k->_filteredDataSource", summary='@"2 elements"') + + self.expect_var_path( + "*k", + type="InheritContainer", + children=[ + ValueCheck( + name="InternalDefiner", + children=[ + ValueCheck(name="NSObject"), + ValueCheck(name="foo", value="2"), + ValueCheck(name="bar", value="3"), + ], + ), + ValueCheck(name="_filteredDataSource", summary='@"2 elements"'), + ], ) - - if strip: - self.expect( - "frame variable *k", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=["foo = 2", "_filteredDataSource = 0x", '"2 elements"'], - ) - else: - self.expect( - "frame variable *k", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - "foo = 2", - "bar = 3", - "_filteredDataSource = 0x", - '"2 elements"', - ], - ) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
