brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 4d439fa Raw
209 lines · python
1"""2Use lldb Python API to test dynamic values in ObjC3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class ObjCDynamicValueTestCase(TestBase):13    def setUp(self):14        # Call super's setUp().15        TestBase.setUp(self)16 17        # Find the line number to break for main.c.18 19        self.source_name = "dynamic-value.m"20        self.set_property_line = line_number(21            self.source_name,22            "// This is the line in setProperty, make sure we step to here.",23        )24        self.handle_SourceBase = line_number(25            self.source_name, "// Break here to check dynamic values."26        )27        self.main_before_setProperty_line = line_number(28            self.source_name, "// Break here to see if we can step into real method."29        )30 31    @add_test_categories(["pyapi"])32    @expectedFailureDarwin("llvm.org/pr20271 rdar://18684107")33    def test_get_objc_dynamic_vals(self):34        """Test fetching ObjC dynamic values."""35        if self.getArchitecture() == "i386":36            # rdar://problem/994649937            self.skipTest("Dynamic types for ObjC V1 runtime not implemented")38 39        self.build()40        exe = self.getBuildArtifact("a.out")41 42        # Create a target from the debugger.43 44        target = self.dbg.CreateTarget(exe)45        self.assertTrue(target, VALID_TARGET)46 47        # Set up our breakpoints:48 49        handle_SourceBase_bkpt = target.BreakpointCreateByLocation(50            self.source_name, self.handle_SourceBase51        )52        self.assertTrue(53            handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1,54            VALID_BREAKPOINT,55        )56 57        main_before_setProperty_bkpt = target.BreakpointCreateByLocation(58            self.source_name, self.main_before_setProperty_line59        )60        self.assertTrue(61            main_before_setProperty_bkpt62            and main_before_setProperty_bkpt.GetNumLocations() == 1,63            VALID_BREAKPOINT,64        )65 66        # Now launch the process, and do not stop at the entry point.67        process = target.LaunchSimple(None, None, self.get_process_working_directory())68 69        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)70 71        threads = lldbutil.get_threads_stopped_at_breakpoint(72            process, main_before_setProperty_bkpt73        )74        self.assertEqual(len(threads), 1)75        thread = threads[0]76 77        #78        #  At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived79        #  make sure we can get that properly:80 81        frame = thread.GetFrameAtIndex(0)82        myObserver = frame.FindVariable("myObserver", lldb.eDynamicCanRunTarget)83        self.assertTrue(myObserver)84        myObserver_source = myObserver.GetChildMemberWithName(85            "_source", lldb.eDynamicCanRunTarget86        )87        self.examine_SourceDerived_ptr(myObserver_source)88 89        #90        # Make sure a static value can be correctly turned into a dynamic91        # value.92 93        frame = thread.GetFrameAtIndex(0)94        myObserver_static = frame.FindVariable("myObserver", lldb.eNoDynamicValues)95        self.assertTrue(myObserver_static)96        myObserver = myObserver_static.GetDynamicValue(lldb.eDynamicCanRunTarget)97        myObserver_source = myObserver.GetChildMemberWithName(98            "_source", lldb.eDynamicCanRunTarget99        )100        self.examine_SourceDerived_ptr(myObserver_source)101 102        # The "frame var" code uses another path to get into children, so let's103        # make sure that works as well:104 105        result = lldb.SBCommandReturnObject()106 107        self.expect(108            "frame var -d run-target myObserver->_source",109            "frame var finds its way into a child member",110            patterns=[r"\(SourceDerived \*\)"],111        )112 113        # check that our ObjC GetISA() does a good job at hiding KVO swizzled114        # classes115 116        self.expect(117            "frame var -d run-target myObserver->_source -T",118            "the KVO-ed class is hidden",119            substrs=["SourceDerived"],120        )121 122        self.expect(123            "frame var -d run-target myObserver->_source -T",124            "the KVO-ed class is hidden",125            matching=False,126            substrs=["NSKVONotify"],127        )128 129        # This test is not entirely related to the main thrust of this test case, but since we're here,130        # try stepping into setProperty, and make sure we get into the version131        # in Source:132 133        thread.StepInto()134 135        threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)136        self.assertEqual(len(threads), 1)137        line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry()138 139        self.assertEqual(line_entry.GetLine(), self.set_property_line)140        self.assertEqual(line_entry.GetFileSpec().GetFilename(), self.source_name)141 142        # Okay, back to the main business.  Continue to the handle_SourceBase143        # and make sure we get the correct dynamic value.144 145        threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)146        self.assertEqual(len(threads), 1)147        thread = threads[0]148 149        frame = thread.GetFrameAtIndex(0)150 151        # Get "object" using FindVariable:152 153        noDynamic = lldb.eNoDynamicValues154        useDynamic = lldb.eDynamicCanRunTarget155 156        object_static = frame.FindVariable("object", noDynamic)157        object_dynamic = frame.FindVariable("object", useDynamic)158 159        # Delete this object to make sure that this doesn't cause havoc with160        # the dynamic object that depends on it.161        del object_static162 163        self.examine_SourceDerived_ptr(object_dynamic)164 165        # Get "this" using FindValue, make sure that works too:166        object_static = frame.FindValue(167            "object", lldb.eValueTypeVariableArgument, noDynamic168        )169        object_dynamic = frame.FindValue(170            "object", lldb.eValueTypeVariableArgument, useDynamic171        )172        del object_static173        self.examine_SourceDerived_ptr(object_dynamic)174 175        # Get "this" using the EvaluateExpression:176        object_static = frame.EvaluateExpression("object", noDynamic)177        object_dynamic = frame.EvaluateExpression("object", useDynamic)178        del object_static179        self.examine_SourceDerived_ptr(object_dynamic)180 181        # Continue again to the handle_SourceBase and make sure we get the correct dynamic value.182        # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so183        # its isa pointer points to SourceBase not NSKVOSourceBase or184        # whatever...185 186        threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)187        self.assertEqual(len(threads), 1)188        thread = threads[0]189 190        frame = thread.GetFrameAtIndex(0)191 192        # Get "object" using FindVariable:193 194        object_static = frame.FindVariable("object", noDynamic)195        object_dynamic = frame.FindVariable("object", useDynamic)196 197        # Delete this object to make sure that this doesn't cause havoc with198        # the dynamic object that depends on it.199        del object_static200 201        self.examine_SourceDerived_ptr(object_dynamic)202 203    def examine_SourceDerived_ptr(self, object):204        self.assertTrue(object)205        self.assertNotEqual(object.GetTypeName().find("SourceDerived"), -1)206        derivedValue = object.GetChildMemberWithName("_derivedValue")207        self.assertTrue(derivedValue)208        self.assertEqual(int(derivedValue.GetValue(), 0), 30)209