|
| 1 | +""" |
| 2 | +Test the "process continue --reverse" and "--forward" options. |
| 3 | +""" |
| 4 | + |
| 5 | + |
| 6 | +import lldb |
| 7 | +from lldbsuite.test.lldbtest import * |
| 8 | +from lldbsuite.test.decorators import * |
| 9 | +from lldbsuite.test.gdbclientutils import * |
| 10 | +from lldbsuite.test.lldbreverse import ReverseTestBase |
| 11 | +from lldbsuite.test import lldbutil |
| 12 | + |
| 13 | + |
| 14 | +class TestReverseContinue(ReverseTestBase): |
| 15 | + @skipIfRemote |
| 16 | + def test_reverse_continue(self): |
| 17 | + target, _, _ = self.setup_recording() |
| 18 | + |
| 19 | + # Set breakpoint and reverse-continue |
| 20 | + trigger_bkpt = target.BreakpointCreateByName("trigger_breakpoint", None) |
| 21 | + self.assertTrue(trigger_bkpt.GetNumLocations() > 0) |
| 22 | + self.expect( |
| 23 | + "process continue --reverse", |
| 24 | + substrs=["stop reason = breakpoint {0}.1".format(trigger_bkpt.GetID())], |
| 25 | + ) |
| 26 | + # `process continue` should preserve current base direction. |
| 27 | + self.expect( |
| 28 | + "process continue", |
| 29 | + STOPPED_DUE_TO_HISTORY_BOUNDARY, |
| 30 | + substrs=["stopped", "stop reason = history boundary"], |
| 31 | + ) |
| 32 | + self.expect( |
| 33 | + "process continue --forward", |
| 34 | + substrs=["stop reason = breakpoint {0}.1".format(trigger_bkpt.GetID())], |
| 35 | + ) |
| 36 | + |
| 37 | + def setup_recording(self): |
| 38 | + """ |
| 39 | + Record execution of code between "start_recording" and "stop_recording" breakpoints. |
| 40 | +
|
| 41 | + Returns with the target stopped at "stop_recording", with recording disabled, |
| 42 | + ready to reverse-execute. |
| 43 | + """ |
| 44 | + self.build() |
| 45 | + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) |
| 46 | + process = self.connect(target) |
| 47 | + |
| 48 | + # Record execution from the start of the function "start_recording" |
| 49 | + # to the start of the function "stop_recording". We want to keep the |
| 50 | + # interval that we record as small as possible to minimize the run-time |
| 51 | + # of our single-stepping recorder. |
| 52 | + start_recording_bkpt = target.BreakpointCreateByName("start_recording", None) |
| 53 | + self.assertTrue(start_recording_bkpt.GetNumLocations() > 0) |
| 54 | + initial_threads = lldbutil.continue_to_breakpoint(process, start_recording_bkpt) |
| 55 | + self.assertEqual(len(initial_threads), 1) |
| 56 | + target.BreakpointDelete(start_recording_bkpt.GetID()) |
| 57 | + self.start_recording() |
| 58 | + stop_recording_bkpt = target.BreakpointCreateByName("stop_recording", None) |
| 59 | + self.assertTrue(stop_recording_bkpt.GetNumLocations() > 0) |
| 60 | + lldbutil.continue_to_breakpoint(process, stop_recording_bkpt) |
| 61 | + target.BreakpointDelete(stop_recording_bkpt.GetID()) |
| 62 | + self.stop_recording() |
| 63 | + |
| 64 | + self.dbg.SetAsync(False) |
| 65 | + |
| 66 | + return target, process, initial_threads |
0 commit comments