brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 53c8cdd Raw
170 lines · python
1import lldb2import time3import unittest4from lldbsuite.test.lldbtest import *5from lldbsuite.test.decorators import *6from lldbsuite.test.gdbclientutils import *7from lldbsuite.test.lldbreverse import ReverseTestBase8from lldbsuite.test import lldbutil9 10 11class TestReverseContinueBreakpoints(ReverseTestBase):12    @skipIfRemote13    def test_reverse_continue(self):14        self.reverse_continue_internal(async_mode=False)15 16    @skipIfRemote17    def test_reverse_continue_async(self):18        self.reverse_continue_internal(async_mode=True)19 20    def reverse_continue_internal(self, async_mode):21        target, process, initial_threads = self.setup_recording(async_mode)22 23        # Reverse-continue. We'll stop at the point where we started recording.24        status = process.ContinueInDirection(lldb.eRunReverse)25        self.assertSuccess(status)26        self.expect_async_state_changes(27            async_mode, process, [lldb.eStateRunning, lldb.eStateStopped]28        )29        self.expect(30            "thread list",31            STOPPED_DUE_TO_HISTORY_BOUNDARY,32            substrs=["stopped", "stop reason = history boundary"],33        )34 35        # Continue forward normally until the target exits.36        status = process.ContinueInDirection(lldb.eRunForward)37        self.expect_async_state_changes(38            async_mode, process, [lldb.eStateRunning, lldb.eStateExited]39        )40        self.assertSuccess(status)41        self.assertState(process.GetState(), lldb.eStateExited)42        self.assertEqual(process.GetExitStatus(), 0)43 44    @skipIfRemote45    def test_reverse_continue_breakpoint(self):46        self.reverse_continue_breakpoint_internal(async_mode=False)47 48    @skipIfRemote49    def test_reverse_continue_breakpoint_async(self):50        self.reverse_continue_breakpoint_internal(async_mode=True)51 52    def reverse_continue_breakpoint_internal(self, async_mode):53        target, process, initial_threads = self.setup_recording(async_mode)54 55        # Reverse-continue to the function "trigger_breakpoint".56        trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None)57        status = process.ContinueInDirection(lldb.eRunReverse)58        self.assertSuccess(status)59        self.expect_async_state_changes(60            async_mode, process, [lldb.eStateRunning, lldb.eStateStopped]61        )62        threads_now = lldbutil.get_threads_stopped_at_breakpoint(process, trigger_bkpt)63        self.assertEqual(threads_now, initial_threads)64 65    @skipIfRemote66    @skipIf(67        oslist=["windows"],68        archs=["x86_64"],69        bugnumber="github.com/llvm/llvm-project/issues/138084",70    )71    def test_reverse_continue_skip_breakpoint(self):72        self.reverse_continue_skip_breakpoint_internal(async_mode=False)73 74    @skipIfRemote75    @skipIf(76        oslist=["windows"],77        archs=["x86_64"],78        bugnumber="github.com/llvm/llvm-project/issues/138084",79    )80    def test_reverse_continue_skip_breakpoint_async(self):81        self.reverse_continue_skip_breakpoint_internal(async_mode=True)82 83    def reverse_continue_skip_breakpoint_internal(self, async_mode):84        target, process, initial_threads = self.setup_recording(async_mode)85 86        # Reverse-continue over a breakpoint at "trigger_breakpoint" whose87        # condition is false (via function call).88        # This tests that we continue in the correct direction after hitting89        # the breakpoint.90        trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None)91        trigger_bkpt.SetCondition("false_condition()")92        status = process.ContinueInDirection(lldb.eRunReverse)93        self.expect_async_state_changes(94            async_mode, process, [lldb.eStateRunning, lldb.eStateStopped]95        )96        self.assertSuccess(status)97        self.expect(98            "thread list",99            STOPPED_DUE_TO_HISTORY_BOUNDARY,100            substrs=["stopped", "stop reason = history boundary"],101        )102 103    @skipIfRemote104    def test_continue_preserves_direction(self):105        self.continue_preserves_direction_internal(async_mode=False)106 107    @skipIfRemote108    def test_continue_preserves_direction_asyhc(self):109        self.continue_preserves_direction_internal(async_mode=True)110 111    def continue_preserves_direction_internal(self, async_mode):112        target, process, initial_threads = self.setup_recording(async_mode)113 114        # Reverse-continue to the function "trigger_breakpoint".115        trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None)116        status = process.ContinueInDirection(lldb.eRunReverse)117        self.assertSuccess(status)118        self.expect_async_state_changes(119            async_mode, process, [lldb.eStateRunning, lldb.eStateStopped]120        )121        # This should continue in reverse.122        status = process.Continue()123        self.expect_async_state_changes(124            async_mode, process, [lldb.eStateRunning, lldb.eStateStopped]125        )126        self.assertSuccess(status)127        self.expect(128            "thread list",129            STOPPED_DUE_TO_HISTORY_BOUNDARY,130            substrs=["stopped", "stop reason = history boundary"],131        )132 133    def setup_recording(self, async_mode):134        """135        Record execution of code between "start_recording" and "stop_recording" breakpoints.136 137        Returns with the target stopped at "stop_recording", with recording disabled,138        ready to reverse-execute.139        """140        self.build()141        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))142        process = self.connect(target)143 144        # Record execution from the start of the function "start_recording"145        # to the start of the function "stop_recording". We want to keep the146        # interval that we record as small as possible to minimize the run-time147        # of our single-stepping recorder.148        start_recording_bkpt = target.BreakpointCreateByName("start_recording", None)149        self.assertTrue(start_recording_bkpt.GetNumLocations() > 0)150        initial_threads = lldbutil.continue_to_breakpoint(process, start_recording_bkpt)151        self.assertEqual(len(initial_threads), 1)152        target.BreakpointDelete(start_recording_bkpt.GetID())153        self.start_recording()154        stop_recording_bkpt = target.BreakpointCreateByName("stop_recording", None)155        self.assertTrue(stop_recording_bkpt.GetNumLocations() > 0)156        lldbutil.continue_to_breakpoint(process, stop_recording_bkpt)157        target.BreakpointDelete(stop_recording_bkpt.GetID())158        self.stop_recording()159 160        self.dbg.SetAsync(async_mode)161        self.expect_async_state_changes(async_mode, process, [lldb.eStateStopped])162 163        return target, process, initial_threads164 165    def expect_async_state_changes(self, async_mode, process, states):166        if not async_mode:167            return168        listener = self.dbg.GetListener()169        lldbutil.expect_state_changes(self, listener, process, states)170