diff --git a/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/Makefile b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/Makefile new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c func.c +include Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/TestGuiBasicDebug.py b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/TestGuiBasicDebug.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/TestGuiBasicDebug.py @@ -0,0 +1,42 @@ +""" +Test the 'gui' shortcuts 's','n','f','u','d' (step in, step over, step out, up, down) +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import PExpectTest + +class TestGuiBasicDebugCommandTest(PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfCursesSupportMissing + def test_gui(self): + self.build() + + self.launch(executable=self.getBuildArtifact("a.out"), dimensions=(100,500)) + self.expect('br set -f main.c -p "// Break here"', substrs=["Breakpoint 1", "address ="]) + self.expect("run", substrs=["stop reason ="]) + + escape_key = chr(27).encode() + + # Start the GUI and close the welcome window. + self.child.sendline("gui") + self.child.send(escape_key) + + # Simulate a simple debugging session. + self.child.send("s") # step + self.child.expect("return 1; // In function[^\r\n]+<<< Thread 1: step in") + self.child.send("u") # up + self.child.expect_exact("func(); // Break here") + self.child.send("d") # down + self.child.expect_exact("return 1; // In function") + self.child.send("f") # finish + self.child.expect("func\(\); // Break here[^\r\n]+<<< Thread 1: step out") + self.child.send("s") # move onto the second one + self.child.expect("func\(\); // Second[^\r\n]+<<< Thread 1: step in") + self.child.send("n") # step over + self.child.expect("return 0;[^\r\n]+<<< Thread 1: step over") + + self.quit() diff --git a/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/func.c b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/func.c new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/func.c @@ -0,0 +1,3 @@ +int func() { + return 1; // In function +} diff --git a/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/main.c b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/main.c new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/gui/basicdebug/main.c @@ -0,0 +1,7 @@ +extern int func(); + +int main(int argc, char **argv) { + func(); // Break here + func(); // Second + return 0; +} diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp --- a/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -3243,6 +3243,8 @@ {'f', "Step out (finish)"}, {'s', "Step in (source line)"}, {'S', "Step in (single instruction)"}, + {'u', "Frame up"}, + {'d', "Frame down"}, {',', "Page up"}, {'.', "Page down"}, {'\0', nullptr}}; @@ -3856,6 +3858,26 @@ } return eKeyHandled; + case 'u': // 'u' == frame up + case 'd': // 'd' == frame down + { + ExecutionContext exe_ctx = + m_debugger.GetCommandInterpreter().GetExecutionContext(); + if (exe_ctx.HasThreadScope()) { + Thread *thread = exe_ctx.GetThreadPtr(); + uint32_t frame_idx = thread->GetSelectedFrameIndex(); + if (frame_idx == UINT32_MAX) + frame_idx = 0; + if (c == 'u' && frame_idx + 1 < thread->GetStackFrameCount()) + ++frame_idx; + else if (c == 'd' && frame_idx > 0) + --frame_idx; + if (thread->SetSelectedFrameByIndex(frame_idx, true)) + exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + } + } + return eKeyHandled; + case 'h': window.CreateHelpSubwindow(); return eKeyHandled;