brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · 844c896 Raw
245 lines · python
1"""Test stepping through ObjC method dispatch in various forms."""2 3import lldb4from lldbsuite.test.decorators import *5from lldbsuite.test.lldbtest import *6from lldbsuite.test import lldbutil7 8 9class TestObjCStepping(TestBase):10    def setUp(self):11        # Call super's setUp().12        TestBase.setUp(self)13        # Find the line numbers that we will step to in main:14        self.main_source = "stepping-tests.m"15        self.source_randomMethod_line = line_number(16            self.main_source, "// Source randomMethod start line."17        )18        self.sourceBase_randomMethod_line = line_number(19            self.main_source, "// SourceBase randomMethod start line."20        )21        self.source_returnsStruct_start_line = line_number(22            self.main_source, "// Source returnsStruct start line."23        )24        self.sourceBase_returnsStruct_start_line = line_number(25            self.main_source, "// SourceBase returnsStruct start line."26        )27        self.stepped_past_nil_line = line_number(28            self.main_source, "// Step over nil should stop here."29        )30 31    @add_test_categories(["pyapi", "basic_process"])32    def test_with_python_api(self):33        """Test stepping through ObjC method dispatch in various forms."""34        self.build()35        exe = self.getBuildArtifact("a.out")36 37        target = self.dbg.CreateTarget(exe)38        self.assertTrue(target, VALID_TARGET)39 40        self.main_source_spec = lldb.SBFileSpec(self.main_source)41 42        breakpoints_to_disable = []43 44        break1 = target.BreakpointCreateBySourceRegex(45            "// Set first breakpoint here.", self.main_source_spec46        )47        self.assertTrue(break1, VALID_BREAKPOINT)48        breakpoints_to_disable.append(break1)49 50        break2 = target.BreakpointCreateBySourceRegex(51            "// Set second breakpoint here.", self.main_source_spec52        )53        self.assertTrue(break2, VALID_BREAKPOINT)54        breakpoints_to_disable.append(break2)55 56        break3 = target.BreakpointCreateBySourceRegex(57            "// Set third breakpoint here.", self.main_source_spec58        )59        self.assertTrue(break3, VALID_BREAKPOINT)60        breakpoints_to_disable.append(break3)61 62        break4 = target.BreakpointCreateBySourceRegex(63            "// Set fourth breakpoint here.", self.main_source_spec64        )65        self.assertTrue(break4, VALID_BREAKPOINT)66        breakpoints_to_disable.append(break4)67 68        break5 = target.BreakpointCreateBySourceRegex(69            "// Set fifth breakpoint here.", self.main_source_spec70        )71        self.assertTrue(break5, VALID_BREAKPOINT)72        breakpoints_to_disable.append(break5)73 74        break_returnStruct_call_super = target.BreakpointCreateBySourceRegex(75            "// Source returnsStruct call line.", self.main_source_spec76        )77        self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT)78        breakpoints_to_disable.append(break_returnStruct_call_super)79 80        break_step_nil = target.BreakpointCreateBySourceRegex(81            "// Set nil step breakpoint here.", self.main_source_spec82        )83        self.assertTrue(break_step_nil, VALID_BREAKPOINT)84 85        # Now launch the process, and do not stop at entry point.86        process = target.LaunchSimple(None, None, self.get_process_working_directory())87 88        self.assertTrue(process, PROCESS_IS_VALID)89 90        # The stop reason of the thread should be breakpoint.91        threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)92        if len(threads) != 1:93            self.fail("Failed to stop at breakpoint 1.")94 95        thread = threads[0]96 97        mySource = thread.GetFrameAtIndex(0).FindVariable("mySource")98        self.assertTrue(mySource, "Found mySource local variable.")99        mySource_isa = mySource.GetChildMemberWithName("isa")100        self.assertTrue(mySource_isa, "Found mySource->isa local variable.")101        className = mySource_isa.GetSummary()102 103        if self.TraceOn():104            print(mySource_isa)105 106        # Lets delete mySource so we can check that after stepping a child variable107        # with no parent persists and is useful.108        del mySource109 110        # Now step in, that should leave us in the Source randomMethod:111        thread.StepInto()112        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()113        self.assertEqual(114            line_number,115            self.source_randomMethod_line,116            "Stepped into Source randomMethod.",117        )118 119        # Now step in again, through the super call, and that should leave us120        # in the SourceBase randomMethod:121        thread.StepInto()122        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()123        self.assertEqual(124            line_number,125            self.sourceBase_randomMethod_line,126            "Stepped through super into SourceBase randomMethod.",127        )128 129        threads = lldbutil.continue_to_breakpoint(process, break2)130        self.assertEqual(len(threads), 1, "Continued to second breakpoint in main.")131 132        # Again, step in twice gets us to a stret method and a stret super133        # call:134        thread = threads[0]135        thread.StepInto()136        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()137        self.assertEqual(138            line_number,139            self.source_returnsStruct_start_line,140            "Stepped into Source returnsStruct.",141        )142 143        threads = lldbutil.continue_to_breakpoint(144            process, break_returnStruct_call_super145        )146        self.assertEqual(147            len(threads), 1, "Stepped to the call super line in Source returnsStruct."148        )149        thread = threads[0]150 151        thread.StepInto()152        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()153        self.assertEqual(154            line_number,155            self.sourceBase_returnsStruct_start_line,156            "Stepped through super into SourceBase returnsStruct.",157        )158 159        # Cool now continue to get past the call that initializes the Observer, and then do our steps in again to see that160        # we can find our way when we're stepping through a KVO swizzled161        # object.162 163        threads = lldbutil.continue_to_breakpoint(process, break3)164        self.assertEqual(165            len(threads),166            1,167            "Continued to third breakpoint in main, our object should now be swizzled.",168        )169 170        newClassName = mySource_isa.GetSummary()171 172        if self.TraceOn():173            print("className is %s, newClassName is %s" % (className, newClassName))174            print(mySource_isa)175 176        self.assertNotEqual(177            newClassName, className, "The isa did indeed change, swizzled!"178        )179 180        # Now step in, that should leave us in the Source randomMethod:181        thread = threads[0]182        thread.StepInto()183        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()184        self.assertEqual(185            line_number,186            self.source_randomMethod_line,187            "Stepped into Source randomMethod in swizzled object.",188        )189 190        # Now step in again, through the super call, and that should leave us191        # in the SourceBase randomMethod:192        thread.StepInto()193        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()194        self.assertEqual(195            line_number,196            self.sourceBase_randomMethod_line,197            "Stepped through super into SourceBase randomMethod in swizzled object.",198        )199 200        threads = lldbutil.continue_to_breakpoint(process, break4)201        self.assertEqual(len(threads), 1, "Continued to fourth breakpoint in main.")202        thread = threads[0]203 204        # Again, step in twice gets us to a stret method and a stret super205        # call:206        thread.StepInto()207        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()208        self.assertEqual(209            line_number,210            self.source_returnsStruct_start_line,211            "Stepped into Source returnsStruct in swizzled object.",212        )213 214        threads = lldbutil.continue_to_breakpoint(215            process, break_returnStruct_call_super216        )217        self.assertEqual(218            len(threads),219            1,220            "Stepped to the call super line in Source returnsStruct - second time.",221        )222        thread = threads[0]223 224        thread.StepInto()225        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()226        self.assertEqual(227            line_number,228            self.sourceBase_returnsStruct_start_line,229            "Stepped through super into SourceBase returnsStruct in swizzled object.",230        )231 232        for bkpt in breakpoints_to_disable:233            bkpt.SetEnabled(False)234 235        threads = lldbutil.continue_to_breakpoint(process, break_step_nil)236        self.assertEqual(len(threads), 1, "Continued to step nil breakpoint.")237 238        thread.StepInto()239        line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()240        self.assertEqual(241            line_number,242            self.stepped_past_nil_line,243            "Step in over dispatch to nil stepped over.",244        )245