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

Reply via email to