brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 86ddabd Raw
205 lines · python
1"""2Test that thread plan listing, and deleting works.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8import lldbsuite.test.lldbutil as lldbutil9from lldbsuite.test.lldbtest import *10 11 12class TestThreadPlanCommands(TestBase):13    NO_DEBUG_INFO_TESTCASE = True14 15    @skipIfWindows16    def test_thread_plan_actions(self):17        self.build()18        self.main_source_file = lldb.SBFileSpec("main.c")19        self.thread_plan_test()20 21    def check_list_output(22        self, command, active_plans=[], completed_plans=[], discarded_plans=[]23    ):24        # Check the "thread plan list" output against a list of active & completed and discarded plans.25        # If all three check arrays are empty, that means the command is expected to fail.26 27        interp = self.dbg.GetCommandInterpreter()28        result = lldb.SBCommandReturnObject()29 30        num_active = len(active_plans)31        num_completed = len(completed_plans)32        num_discarded = len(discarded_plans)33 34        interp.HandleCommand(command, result)35        print("Command: %s" % (command))36        print(result.GetOutput())37 38        if num_active == 0 and num_completed == 0 and num_discarded == 0:39            self.assertFalse(40                result.Succeeded(),41                "command: '%s' succeeded when it should have failed: '%s'"42                % (command, result.GetError()),43            )44            return45 46        self.assertTrue(47            result.Succeeded(),48            "command: '%s' failed: '%s'" % (command, result.GetError()),49        )50        result_arr = result.GetOutput().splitlines()51        num_results = len(result_arr)52 53        # Now iterate through the results array and pick out the results.54        result_idx = 055        self.assertIn("thread #", result_arr[result_idx], "Found thread header")56        result_idx += 157        self.assertIn(58            "Active plan stack", result_arr[result_idx], "Found active header"59        )60        result_idx += 161        self.assertIn(62            "Element 0: Base thread plan", result_arr[result_idx], "Found base plan"63        )64        result_idx += 165 66        for text in active_plans:67            self.assertIn(68                text, result_arr[result_idx], "Didn't find active plan: %s" % (text)69            )70            result_idx += 171 72        if len(completed_plans) > 0:73            # First consume any remaining active plans:74            while not "Completed plan stack:" in result_arr[result_idx]:75                result_idx += 176                if result_idx == num_results:77                    self.fail(78                        "There should have been completed plans, but I never saw the completed stack header"79                    )80            # We are at the Completed header, skip it:81            result_idx += 182            for text in completed_plans:83                self.assertIn(84                    text,85                    result_arr[result_idx],86                    "Didn't find completed plan: %s" % (text),87                )88                result_idx += 189 90        if len(discarded_plans) > 0:91            # First consume any remaining completed plans:92            while not "Discarded plan stack:" in result_arr[result_idx]:93                result_idx += 194                if result_idx == num_results:95                    self.fail(96                        "There should have been discarded plans, but I never saw the discarded stack header"97                    )98 99            # We are at the Discarded header, skip it:100            result_idx += 1101            for text in discarded_plans:102                self.assertIn(103                    text,104                    result_arr[result_idx],105                    "Didn't find discarded plan: %s" % (text),106                )107                result_idx += 1108 109    def thread_plan_test(self):110        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(111            self, "Set a breakpoint here", self.main_source_file112        )113 114        # We need to have an internal plan so we can test listing one.115        # The most consistent way to do that is to use a scripted thread plan116        # that uses a sub-plan.  Source that in now.117        source_path = os.path.join(self.getSourceDir(), "wrap_step_over.py")118        self.runCmd("command script import '%s'" % (source_path))119 120        # Now set a breakpoint that we will hit by running our scripted step.121        call_me_bkpt = target.BreakpointCreateBySourceRegex(122            "Set another here", self.main_source_file123        )124        self.assertGreater(125            call_me_bkpt.GetNumLocations(), 0, "Set the breakpoint successfully"126        )127        thread.StepUsingScriptedThreadPlan("wrap_step_over.WrapStepOver")128        threads = lldbutil.get_threads_stopped_at_breakpoint(process, call_me_bkpt)129        self.assertEqual(len(threads), 1, "Hit my breakpoint while stepping over")130 131        current_id = threads[0].GetIndexID()132        current_tid = threads[0].GetThreadID()133        # Run thread plan list without the -i flag:134        command = "thread plan list %d" % (current_id)135        self.check_list_output(command, ["wrap_step_over.WrapStepOver"], [])136 137        # Run thread plan list with the -i flag:138        command = "thread plan list -i %d" % (current_id)139        self.check_list_output(command, ["WrapStepOver", "Stepping over line main.c"])140 141        # Run thread plan list providing TID, output should be the same:142        command = "thread plan list -t %d" % (current_tid)143        self.check_list_output(command, ["wrap_step_over.WrapStepOver"])144 145        # Provide both index & tid, and make sure we only print once:146        command = "thread plan list -t %d %d" % (current_tid, current_id)147        self.check_list_output(command, ["wrap_step_over.WrapStepOver"])148 149        # Try a fake TID, and make sure that fails:150        fake_tid = 0151        for i in range(100, 10000, 100):152            fake_tid = current_tid + i153            thread = process.GetThreadByID(fake_tid)154            if not thread:155                break156 157        command = "thread plan list -t %d" % (fake_tid)158        self.check_list_output(command)159 160        # Now continue, and make sure we printed the completed plan:161        process.Continue()162        threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)163        self.assertEqual(len(threads), 1, "One thread completed a step")164 165        # Run thread plan list - there aren't any private plans at this point:166        command = "thread plan list %d" % (current_id)167        self.check_list_output(command, [], ["wrap_step_over.WrapStepOver"])168 169        # Set another breakpoint that we can run to, to try deleting thread plans.170        second_step_bkpt = target.BreakpointCreateBySourceRegex(171            "Run here to step over again", self.main_source_file172        )173        self.assertGreater(174            second_step_bkpt.GetNumLocations(), 0, "Set the breakpoint successfully"175        )176        final_bkpt = target.BreakpointCreateBySourceRegex(177            "Make sure we get here on last continue", self.main_source_file178        )179        self.assertGreater(180            final_bkpt.GetNumLocations(), 0, "Set the breakpoint successfully"181        )182 183        threads = lldbutil.continue_to_breakpoint(process, second_step_bkpt)184        self.assertEqual(len(threads), 1, "Hit the second step breakpoint")185 186        threads[0].StepOver()187        threads = lldbutil.get_threads_stopped_at_breakpoint(process, call_me_bkpt)188 189        result = lldb.SBCommandReturnObject()190        interp = self.dbg.GetCommandInterpreter()191        interp.HandleCommand("thread plan discard 1", result)192        self.assertTrue(193            result.Succeeded(), "Deleted the step over plan: %s" % (result.GetOutput())194        )195 196        # Make sure the plan gets listed in the discarded plans:197        command = "thread plan list %d" % (current_id)198        self.check_list_output(command, [], [], ["Stepping over line main.c:"])199 200        process.Continue()201        threads = lldbutil.get_threads_stopped_at_breakpoint(process, final_bkpt)202        self.assertEqual(len(threads), 1, "Ran to final breakpoint")203        threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)204        self.assertEqual(len(threads), 0, "Did NOT complete the step over plan")205