brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · adf3e2a Raw
157 lines · python
1"""2Test stepping out from a function in a multi-threaded program.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class ThreadStepOutTestCase(TestBase):13    @skipIfWindows  # This test will hang on windows llvm.org/pr2175314    @expectedFailureAll(oslist=["windows"])15    @expectedFailureNetBSD16    def test_step_single_thread(self):17        """Test thread step out on one thread via command interpreter."""18        self.build()19        self.step_out_test(self.step_out_single_thread_with_cmd)20 21    @skipIfWindows  # This test will hang on windows llvm.org/pr2175322    @expectedFailureAll(oslist=["windows"])23    @expectedFailureAll(24        oslist=["watchos"], archs=["armv7k"], bugnumber="rdar://problem/34674488"25    )  # stop reason is trace when it should be step-out26    @expectedFailureNetBSD27    def test_step_all_threads(self):28        """Test thread step out on all threads via command interpreter."""29        self.build()30        self.step_out_test(self.step_out_all_threads_with_cmd)31 32    @skipIfWindows  # This test will hang on windows llvm.org/pr2175333    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24681")34    @expectedFailureNetBSD35    def test_python(self):36        """Test thread step out on one thread via Python API (dwarf)."""37        self.build()38        self.step_out_test(self.step_out_with_python)39 40    def setUp(self):41        # Call super's setUp().42        TestBase.setUp(self)43        # Find the line number for our breakpoint.44        self.bkpt_string = "// Set breakpoint here"45        self.breakpoint = line_number("main.cpp", self.bkpt_string)46        self.step_in_line = line_number("main.cpp", "// But we might still be here")47        self.step_out_dest = line_number(48            "main.cpp", "// Expect to stop here after step-out."49        )50 51    def check_stepping_thread(self):52        zeroth_frame = self.step_out_thread.frames[0]53        line_entry = zeroth_frame.line_entry54        self.assertTrue(line_entry.IsValid(), "Stopped at a valid line entry")55        self.assertEqual("main.cpp", line_entry.file.basename, "Still in main.cpp")56        # We can't really tell whether we stay on our line57        # or get to the next line, it depends on whether there are any58        # instructions between the call and the return.59        line = line_entry.line60        self.assertTrue(61            line == self.step_out_dest or line == self.step_in_line,62            "Stepped to the wrong line: {0}".format(line),63        )64 65    def step_out_single_thread_with_cmd(self):66        other_threads = {}67        for thread in self.process.threads:68            if thread.GetIndexID() == self.step_out_thread.GetIndexID():69                continue70            other_threads[thread.GetIndexID()] = thread.frames[0].line_entry71 72        # There should be other threads...73        self.assertNotEqual(len(other_threads), 0)74        self.step_out_with_cmd("this-thread")75        # The other threads should not have made progress:76        for thread in self.process.threads:77            index_id = thread.GetIndexID()78            line_entry = other_threads.get(index_id)79            if line_entry:80                self.assertEqual(81                    thread.frames[0].line_entry.file.basename,82                    line_entry.file.basename,83                    "Thread {0} moved by file".format(index_id),84                )85                self.assertEqual(86                    thread.frames[0].line_entry.line,87                    line_entry.line,88                    "Thread {0} moved by line".format(index_id),89                )90 91    def step_out_all_threads_with_cmd(self):92        self.step_out_with_cmd("all-threads")93 94    def step_out_with_cmd(self, run_mode):95        self.runCmd("thread select %d" % self.step_out_thread.GetIndexID())96        self.runCmd("thread step-out -m %s" % run_mode)97        self.expect(98            "process status",99            "Expected stop reason to be step-out",100            substrs=["stop reason = step out"],101        )102 103        selected_thread = self.process.GetSelectedThread()104        self.assertEqual(105            selected_thread.GetIndexID(),106            self.step_out_thread.GetIndexID(),107            "Step out changed selected thread.",108        )109        self.check_stepping_thread()110 111    def step_out_with_python(self):112        self.step_out_thread.StepOut()113 114        reason = self.step_out_thread.GetStopReason()115        self.assertEqual(116            lldb.eStopReasonPlanComplete,117            reason,118            "Expected thread stop reason 'plancomplete', but got '%s'"119            % lldbutil.stop_reason_to_str(reason),120        )121        self.check_stepping_thread()122 123    def step_out_test(self, step_out_func):124        """Test single thread step out of a function."""125        (126            self.inferior_target,127            self.process,128            thread,129            bkpt,130        ) = lldbutil.run_to_source_breakpoint(131            self, self.bkpt_string, lldb.SBFileSpec("main.cpp"), only_one_thread=False132        )133 134        # We hit the breakpoint on at least one thread.  If we hit it on both threads135        # simultaneously, we can try the step out.  Otherwise, suspend the thread136        # that hit the breakpoint, and continue till the second thread hits137        # the breakpoint:138 139        (breakpoint_threads, other_threads) = ([], [])140        lldbutil.sort_stopped_threads(141            self.process,142            breakpoint_threads=breakpoint_threads,143            other_threads=other_threads,144        )145        if len(breakpoint_threads) == 1:146            success = thread.Suspend()147            self.assertTrue(success, "Couldn't suspend a thread")148            breakpoint_threads = lldbutil.continue_to_breakpoint(self.process, bkpt)149            self.assertEqual(len(breakpoint_threads), 2, "Second thread stopped")150            success = thread.Resume()151            self.assertTrue(success, "Couldn't resume a thread")152 153        self.step_out_thread = breakpoint_threads[0]154 155        # Step out of thread stopped at breakpoint156        step_out_func()157