Make the unwinding of the stack part of "thread return" work, and add the thread return command.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@163867 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 93ecf36..f7f070e 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private.h"
#include "lldb/Core/State.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Host/Host.h"
@@ -1244,6 +1245,107 @@
}
};
+class CommandObjectThreadReturn : public CommandObjectRaw
+{
+public:
+ CommandObjectThreadReturn (CommandInterpreter &interpreter) :
+ CommandObjectRaw (interpreter,
+ "thread return",
+ "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.",
+ "thread return",
+ eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ {
+ CommandArgumentEntry arg;
+ CommandArgumentData expression_arg;
+
+ // Define the first (and only) variant of this arg.
+ expression_arg.arg_type = eArgTypeExpression;
+ expression_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (expression_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
+
+
+ }
+
+ ~CommandObjectThreadReturn()
+ {
+ }
+
+protected:
+
+ bool DoExecute
+ (
+ const char *command,
+ CommandReturnObject &result
+ )
+ {
+ // If there is a command string, pass it to the expression parser:
+ ExecutionContext exe_ctx = m_interpreter.GetExecutionContext();
+ if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope()))
+ {
+ result.AppendError("Must have selected process, thread and frame for thread return.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ ValueObjectSP return_valobj_sp;
+
+ StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+ uint32_t frame_idx = frame_sp->GetFrameIndex();
+
+ if (frame_sp->IsInlined())
+ {
+ result.AppendError("Don't know how to return from inlined frames.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (command && command[0] != '\0')
+ {
+ Target *target = exe_ctx.GetTargetPtr();
+ Target::EvaluateExpressionOptions options;
+
+ options.SetUnwindOnError(true);
+ options.SetUseDynamic(eNoDynamicValues);
+
+ ExecutionResults exe_results = eExecutionSetupError;
+ exe_results = target->EvaluateExpression (command,
+ frame_sp.get(),
+ return_valobj_sp,
+ options);
+ if (exe_results != eExecutionCompleted)
+ {
+ if (return_valobj_sp)
+ result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
+ else
+ result.AppendErrorWithFormat("Unknown error evaluating result expression.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+
+ }
+ }
+
+ Error error;
+ ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp);
+ if (!error.Success())
+ {
+ result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ thread_sp->GetStatus(result.GetOutputStream(), 0, 1, 1);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
+};
+
//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
//-------------------------------------------------------------------------
@@ -1257,6 +1359,7 @@
LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
+ LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (