[lldb][gui] make 'step out' step out of the selected frame

Differential Revision: https://reviews.llvm.org/D123001
This commit is contained in:
Luboš Luňák 2022-04-03 20:19:10 +02:00
parent f90fa55569
commit 76bc772920
6 changed files with 47 additions and 11 deletions

View file

@ -539,9 +539,12 @@ public:
/// This function is designed to be used by commands where the
/// process is publicly stopped.
///
/// \param[in] frame_idx
/// The frame index to step out of.
///
/// \return
/// An error that describes anything that went wrong
virtual Status StepOut();
virtual Status StepOut(uint32_t frame_idx = 0);
/// Retrieves the per-thread data area.
/// Most OSs maintain a per-thread pointer (e.g. the FS register on
@ -836,7 +839,7 @@ public:
/// See standard meanings for the stop & run votes in ThreadPlan.h.
///
/// \param[in] frame_idx
/// The fame index.
/// The frame index.
///
/// \param[out] status
/// A status with an error if queuing failed.

View file

@ -6402,8 +6402,11 @@ public:
if (exe_ctx.HasThreadScope()) {
Process *process = exe_ctx.GetProcessPtr();
if (process && process->IsAlive() &&
StateIsStoppedState(process->GetState(), true))
exe_ctx.GetThreadRef().StepOut();
StateIsStoppedState(process->GetState(), true)) {
Thread *thread = exe_ctx.GetThreadPtr();
uint32_t frame_idx = thread->GetSelectedFrameIndex();
exe_ctx.GetThreadRef().StepOut(frame_idx);
}
}
}
return MenuActionResult::Handled;
@ -7361,7 +7364,9 @@ public:
m_debugger.GetCommandInterpreter().GetExecutionContext();
if (exe_ctx.HasThreadScope() &&
StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) {
exe_ctx.GetThreadRef().StepOut();
Thread *thread = exe_ctx.GetThreadPtr();
uint32_t frame_idx = thread->GetSelectedFrameIndex();
exe_ctx.GetThreadRef().StepOut(frame_idx);
}
}
return eKeyHandled;

View file

@ -1953,7 +1953,7 @@ Status Thread::StepOver(bool source_step,
return error;
}
Status Thread::StepOut() {
Status Thread::StepOut(uint32_t frame_idx) {
Status error;
Process *process = GetProcess().get();
if (StateIsStoppedState(process->GetState(), true)) {
@ -1963,7 +1963,7 @@ Status Thread::StepOut() {
ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut(
abort_other_plans, nullptr, first_instruction, stop_other_threads,
eVoteYes, eVoteNoOpinion, 0, error));
eVoteYes, eVoteNoOpinion, frame_idx, error));
new_plan_sp->SetIsControllingPlan(true);
new_plan_sp->SetOkayToDiscard(false);

View file

@ -32,7 +32,7 @@ class TestGuiBasicDebugCommandTest(PExpectTest):
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.expect_exact("func(); // Break here")
self.child.send("d") # down
self.child.expect_exact("return 1; // In function")
self.child.send("f") # finish
@ -40,7 +40,19 @@ class TestGuiBasicDebugCommandTest(PExpectTest):
self.child.send("s") # move onto the second one
self.child.expect("<<< Thread 1: step in")
self.child.send("n") # step over
self.child.expect("<<< Thread 1: step over")
self.child.expect("// Dummy command 1[^\r\n]+<<< Thread 1: step over")
self.child.send("n")
# Test that 'up' + 'step out' steps out of the selected function.
self.child.send("s") # move into func_up()
self.child.expect("// In func_up")
self.child.send("s") # move into func_down()
self.child.expect("// In func_down")
self.child.send("u") # up
self.child.expect("// In func_up")
self.child.send("f") # finish
self.child.expect("// Dummy command 2[^\r\n]+<<< Thread 1: step out")
self.child.send("n")
# Press escape to quit the gui
self.child.send(escape_key)

View file

@ -1,3 +1,12 @@
int func() {
return 1; // In function
}
void func_down() {
int dummy = 1; // In func_down
(void)dummy;
}
void func_up() {
func_down(); // In func_up
}

View file

@ -1,7 +1,14 @@
extern int func();
extern void func_up();
int main(int argc, char **argv) {
func(); // Break here
func(); // Second
int dummy;
func(); // Break here
func(); // Second
dummy = 1; // Dummy command 1
func_up(); // First func1 call
dummy = 2; // Dummy command 2
return 0;
}