brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 5710244 Raw
207 lines · python
1"""2Test that we page getting a long backtrace on more than one thread3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class TestThreadBacktracePage(TestBase):13    NO_DEBUG_INFO_TESTCASE = True14 15    def test_thread_backtrace_one_thread(self):16        """Run a simplified version of the test that just hits one breakpoint and17        doesn't care about synchronizing the two threads - hopefully this will18        run on more systems."""19        self.build()20        (21            self.inferior_target,22            self.process,23            thread,24            bkpt,25        ) = lldbutil.run_to_source_breakpoint(26            self, self.bkpt_string, lldb.SBFileSpec("main.cpp"), only_one_thread=False27        )28 29        # We hit the breakpoint on at least one thread.  If we hit it on both threads30        # simultaneously, we are ready to run our tests.  Otherwise, suspend the thread31        # that hit the breakpoint, and continue till the second thread hits32        # the breakpoint:33 34        (breakpoint_threads, other_threads) = ([], [])35        lldbutil.sort_stopped_threads(36            self.process,37            breakpoint_threads=breakpoint_threads,38            other_threads=other_threads,39        )40        self.assertGreater(41            len(breakpoint_threads), 0, "We hit at least one breakpoint thread"42        )43        self.assertGreater(len(breakpoint_threads[0].frames), 2, "I can go up")44        thread_id = breakpoint_threads[0].idx45        name = breakpoint_threads[0].frame[1].name.split("(")[0]46        self.check_one_thread(thread_id, name)47 48    def setUp(self):49        # Call super's setUp().50        TestBase.setUp(self)51        # Find the line number for our breakpoint.52        self.bkpt_string = "// Set breakpoint here"53 54    def check_one_thread(self, thread_id, func_name):55        # Now issue some thread backtrace commands and make sure they56        # get the right answer back.57        interp = self.dbg.GetCommandInterpreter()58        result = lldb.SBCommandReturnObject()59 60        # Run the real backtrace, remember to pass True for add_to_history since61        # we don't generate repeat commands for commands that aren't going into the history.62        interp.HandleCommand(63            "thread backtrace --count 10 {0}".format(thread_id), result, True64        )65        self.assertTrue(result.Succeeded(), "bt with count succeeded")66        # There should be 11 lines:67        lines = result.GetOutput().splitlines()68        self.assertEqual(len(lines), 11, "Got the right number of lines")69        # First frame is stop_here:70        self.assertNotEqual(lines[1].find("stop_here"), -1, "Found Stop Here")71        for line in lines[2:10]:72            self.assertNotEqual(73                line.find(func_name),74                -1,75                "Name {0} not found in line: {1}".format(func_name, line),76            )77        # The last entry should be 43:78        self.assertNotEqual(lines[10].find("count=43"), -1, "First show ends at 43")79 80        # Now try a repeat, and make sure we get 10 more on this thread:81        # import pdb; pdb.set_trace()82        interp.HandleCommand("", result, True)83        self.assertTrue(84            result.Succeeded(), "repeat command failed: {0}".format(result.GetError())85        )86        lines = result.GetOutput().splitlines()87        self.assertEqual(len(lines), 11, "Repeat got 11 lines")88        # Every line should now be the recurse function:89        for line in lines[1:10]:90            self.assertNotEqual(line.find(func_name), -1, "Name in every line")91        self.assertNotEqual(lines[10].find("count=33"), -1, "Last one is now 33")92 93    def check_two_threads(94        self, result_str, thread_id_1, name_1, thread_id_2, name_2, start_idx, end_idx95    ):96        # We should have 2 occurrences ot the thread header:97        self.assertEqual(98            result_str.count("thread #{0}".format(thread_id_1)), 1, "One for thread 1"99        )100        self.assertEqual(101            result_str.count("thread #{0}".format(thread_id_2)), 1, "One for thread 2"102        )103        # We should have 10 occurrences of each name:104        self.assertEqual(result_str.count(name_1), 10, "Found 10 of {0}".format(name_1))105        self.assertEqual(result_str.count(name_2), 10, "Found 10 of {0}".format(name_1))106        # There should be two instances of count=<start_idx> and none of count=<start-1>:107        self.assertEqual(108            result_str.count("count={0}".format(start_idx)),109            2,110            "Two instances of start_idx",111        )112        self.assertEqual(113            result_str.count("count={0}".format(start_idx - 1)),114            0,115            "No instances of start_idx - 1",116        )117        # There should be two instances of count=<end_idx> and none of count=<end_idx+1>:118        self.assertEqual(119            result_str.count("count={0}".format(end_idx)), 2, "Two instances of end_idx"120        )121        self.assertEqual(122            result_str.count("count={0}".format(end_idx + 1)),123            0,124            "No instances after end idx",125        )126 127    # The setup of this test was copied from the step-out test, and I can't tell from128    # the comments whether it was getting two threads to the same breakpoint that was129    # problematic, or the step-out part.  This test stops at the rendevous point so I'm130    # removing the skipIfLinux to see if we see any flakiness in just this part of the test.131    @skipIfWindows  # This test will hang on windows llvm.org/pr21753132    @expectedFailureAll(oslist=["windows"])133    @expectedFailureNetBSD134    def test_thread_backtrace_two_threads(self):135        """Test that repeat works even when backtracing on more than one thread."""136        self.build()137        (138            self.inferior_target,139            self.process,140            thread,141            bkpt,142        ) = lldbutil.run_to_source_breakpoint(143            self, self.bkpt_string, lldb.SBFileSpec("main.cpp"), only_one_thread=False144        )145 146        # We hit the breakpoint on at least one thread.  If we hit it on both threads147        # simultaneously, we are ready to run our tests.  Otherwise, suspend the thread148        # that hit the breakpoint, and continue till the second thread hits149        # the breakpoint:150 151        (breakpoint_threads, other_threads) = ([], [])152        lldbutil.sort_stopped_threads(153            self.process,154            breakpoint_threads=breakpoint_threads,155            other_threads=other_threads,156        )157        if len(breakpoint_threads) == 1:158            success = thread.Suspend()159            self.assertTrue(success, "Couldn't suspend a thread")160            breakpoint_threads = lldbutil.continue_to_breakpoint(self.process, bkpt)161            self.assertEqual(len(breakpoint_threads), 2, "Second thread stopped")162 163        # Figure out which thread is which:164        thread_id_1 = breakpoint_threads[0].idx165        self.assertGreater(len(breakpoint_threads[0].frames), 2, "I can go up")166        name_1 = breakpoint_threads[0].frame[1].name.split("(")[0]167 168        thread_id_2 = breakpoint_threads[1].idx169        self.assertGreater(len(breakpoint_threads[1].frames), 2, "I can go up")170        name_2 = breakpoint_threads[1].frame[1].name.split("(")[0]171 172        # Check that backtrace and repeat works on one thread, then works on the second173        # when we switch to it:174        self.check_one_thread(thread_id_1, name_1)175        self.check_one_thread(thread_id_2, name_2)176 177        # The output is looking right at this point, let's just do a couple more quick checks178        # to see we handle two threads and a start count:179        interp = self.dbg.GetCommandInterpreter()180        result = lldb.SBCommandReturnObject()181 182        interp.HandleCommand(183            "thread backtrace --count 10 --start 10 {0} {1}".format(184                thread_id_1, thread_id_2185            ),186            result,187            True,188        )189        self.assertTrue(result.Succeeded(), "command succeeded for two threads")190 191        result.Clear()192        interp.HandleCommand("", result, True)193        self.assertTrue(result.Succeeded(), "repeat command succeeded for two threads")194        result_str = result.GetOutput()195        self.check_two_threads(196            result_str, thread_id_1, name_1, thread_id_2, name_2, 23, 32197        )198 199        # Finally make sure the repeat repeats:200        result.Clear()201        interp.HandleCommand("", result, True)202        self.assertTrue(result.Succeeded(), "repeat command succeeded for two threads")203        result_str = result.GetOutput()204        self.check_two_threads(205            result_str, thread_id_1, name_1, thread_id_2, name_2, 13, 22206        )207