summaryrefslogtreecommitdiff
path: root/source/Expression
diff options
context:
space:
mode:
Diffstat (limited to 'source/Expression')
-rw-r--r--source/Expression/ClangFunction.cpp158
-rw-r--r--source/Expression/ClangUserExpression.cpp89
-rw-r--r--source/Expression/Materializer.cpp5
3 files changed, 75 insertions, 177 deletions
diff --git a/source/Expression/ClangFunction.cpp b/source/Expression/ClangFunction.cpp
index b37044df9ecc7..e707c60ffced6 100644
--- a/source/Expression/ClangFunction.cpp
+++ b/source/Expression/ClangFunction.cpp
@@ -394,14 +394,9 @@ ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_add
ThreadPlan *
ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t func_addr,
- lldb::addr_t &args_addr,
- Stream &errors,
- bool stop_others,
- bool unwind_on_error,
- bool ignore_breakpoints,
- lldb::addr_t *this_arg,
- lldb::addr_t *cmd_arg)
+ lldb::addr_t args_addr,
+ const EvaluateExpressionOptions &options,
+ Stream &errors)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
@@ -418,16 +413,15 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
// Okay, now run the function:
- Address wrapper_address (func_addr);
+ Address wrapper_address (m_jit_start_addr);
+
+ lldb::addr_t args = { args_addr };
+
ThreadPlan *new_plan = new ThreadPlanCallFunction (*thread,
wrapper_address,
ClangASTType(),
- args_addr,
- stop_others,
- unwind_on_error,
- ignore_breakpoints,
- this_arg,
- cmd_arg);
+ args,
+ options);
new_plan->SetIsMasterPlan(true);
new_plan->SetOkayToDiscard (false);
return new_plan;
@@ -479,63 +473,48 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_
}
ExecutionResults
-ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
-{
- return ExecuteFunction (exe_ctx, errors, 1000, true, results);
-}
-
-ExecutionResults
-ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
-{
- const bool try_all_threads = false;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = true;
- return ExecuteFunction (exe_ctx, NULL, errors, stop_others, 0UL, try_all_threads,
- unwind_on_error, ignore_breakpoints, results);
-}
-
-ExecutionResults
ClangFunction::ExecuteFunction(
ExecutionContext &exe_ctx,
+ lldb::addr_t *args_addr_ptr,
+ const EvaluateExpressionOptions &options,
Stream &errors,
- uint32_t timeout_usec,
- bool try_all_threads,
Value &results)
{
- const bool stop_others = true;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = true;
- return ExecuteFunction (exe_ctx, NULL, errors, stop_others, timeout_usec,
- try_all_threads, unwind_on_error, ignore_breakpoints, results);
-}
+ using namespace clang;
+ ExecutionResults return_value = eExecutionSetupError;
+
+ // ClangFunction::ExecuteFunction execution is always just to get the result. Do make sure we ignore
+ // breakpoints, unwind on error, and don't try to debug it.
+ EvaluateExpressionOptions real_options = options;
+ real_options.SetDebug(false);
+ real_options.SetUnwindOnError(true);
+ real_options.SetIgnoreBreakpoints(true);
+
+ lldb::addr_t args_addr;
+
+ if (args_addr_ptr != NULL)
+ args_addr = *args_addr_ptr;
+ else
+ args_addr = LLDB_INVALID_ADDRESS;
+
+ if (CompileFunction(errors) != 0)
+ return eExecutionSetupError;
+
+ if (args_addr == LLDB_INVALID_ADDRESS)
+ {
+ if (!InsertFunction(exe_ctx, args_addr, errors))
+ return eExecutionSetupError;
+ }
-// This is the static function
-ExecutionResults
-ClangFunction::ExecuteFunction (
- ExecutionContext &exe_ctx,
- lldb::addr_t function_address,
- lldb::addr_t &void_arg,
- bool stop_others,
- bool try_all_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
- uint32_t timeout_usec,
- Stream &errors,
- lldb::addr_t *this_arg)
-{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
log->Printf("== [ClangFunction::ExecuteFunction] Executing function ==");
- lldb::ThreadPlanSP call_plan_sp (ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
- function_address,
- void_arg,
- errors,
- stop_others,
- unwind_on_error,
- ignore_breakpoints,
- this_arg));
+ lldb::ThreadPlanSP call_plan_sp (GetThreadPlanToCallFunction (exe_ctx,
+ args_addr,
+ real_options,
+ errors));
if (!call_plan_sp)
return eExecutionSetupError;
@@ -544,17 +523,14 @@ ClangFunction::ExecuteFunction (
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
- ExecutionResults results = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx, call_plan_sp,
- stop_others,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
- errors);
+ return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ real_options,
+ errors);
if (log)
{
- if (results != eExecutionCompleted)
+ if (return_value != eExecutionCompleted)
{
log->Printf("== [ClangFunction::ExecuteFunction] Execution completed abnormally ==");
}
@@ -567,50 +543,6 @@ ClangFunction::ExecuteFunction (
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
- return results;
-}
-
-ExecutionResults
-ClangFunction::ExecuteFunction(
- ExecutionContext &exe_ctx,
- lldb::addr_t *args_addr_ptr,
- Stream &errors,
- bool stop_others,
- uint32_t timeout_usec,
- bool try_all_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
- Value &results)
-{
- using namespace clang;
- ExecutionResults return_value = eExecutionSetupError;
-
- lldb::addr_t args_addr;
-
- if (args_addr_ptr != NULL)
- args_addr = *args_addr_ptr;
- else
- args_addr = LLDB_INVALID_ADDRESS;
-
- if (CompileFunction(errors) != 0)
- return eExecutionSetupError;
-
- if (args_addr == LLDB_INVALID_ADDRESS)
- {
- if (!InsertFunction(exe_ctx, args_addr, errors))
- return eExecutionSetupError;
- }
-
- return_value = ClangFunction::ExecuteFunction (exe_ctx,
- m_jit_start_addr,
- args_addr,
- stop_others,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
- errors);
-
if (args_addr_ptr != NULL)
*args_addr_ptr = args_addr;
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index e4f2830ba259f..d9ecd41be97a4 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -716,35 +716,6 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
return true;
}
-ThreadPlan *
-ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
- ExecutionContext &exe_ctx)
-{
- lldb::addr_t struct_address;
-
- lldb::addr_t object_ptr = 0;
- lldb::addr_t cmd_ptr = 0;
-
- PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
-
- // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
- // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
- // forcing unwind_on_error to be true here, in practical terms that can't happen.
-
- const bool stop_others = true;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = false;
- return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
- m_jit_start_addr,
- struct_address,
- error_stream,
- stop_others,
- unwind_on_error,
- ignore_breakpoints,
- (m_needs_object_ptr ? &object_ptr : NULL),
- (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
-}
-
bool
ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
ExecutionContext &exe_ctx,
@@ -852,27 +823,22 @@ ClangUserExpression::Execute (Stream &error_stream,
}
else
{
- const uint32_t timeout_usec = options.GetTimeoutUsec();
- const bool debug = options.GetDebug();
- const bool unwind_on_error = debug ? false : options.DoesUnwindOnError();
- const bool ignore_breakpoints = debug ? false : options.DoesIgnoreBreakpoints();
- const bool stop_others = true;
- const bool try_all_threads = options.GetRunOthers();
- lldb::BreakpointSP debug_bkpt_sp;
- if (debug)
- {
- // TODO: push this down into the thread plan and let the plan manage it
- debug_bkpt_sp = exe_ctx.GetTargetRef().CreateBreakpoint(m_jit_start_addr, false, false);
- }
Address wrapper_address (m_jit_start_addr);
+
+ llvm::SmallVector <lldb::addr_t, 3> args;
+
+ if (m_needs_object_ptr) {
+ args.push_back(object_ptr);
+ if (m_objectivec)
+ args.push_back(cmd_ptr);
+ }
+
+ args.push_back(struct_address);
+
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
wrapper_address,
- struct_address,
- stop_others,
- unwind_on_error,
- ignore_breakpoints,
- (m_needs_object_ptr ? &object_ptr : NULL),
- ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
+ args,
+ options,
shared_ptr_to_me));
if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
@@ -890,19 +856,10 @@ ClangUserExpression::Execute (Stream &error_stream,
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
- call_plan_sp,
- stop_others,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
+ call_plan_sp,
+ options,
error_stream);
- if (debug_bkpt_sp)
- {
- exe_ctx.GetTargetRef().RemoveBreakpointByID(debug_bkpt_sp->GetID());
- }
-
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
@@ -922,16 +879,22 @@ ClangUserExpression::Execute (Stream &error_stream,
if (error_desc)
error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
else
- error_stream.Printf ("Execution was interrupted.");
+ error_stream.PutCString ("Execution was interrupted.");
- if ((execution_result == eExecutionInterrupted && unwind_on_error)
- || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
- error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
+ if ((execution_result == eExecutionInterrupted && options.DoesUnwindOnError())
+ || (execution_result == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
+ error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
else
- error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
+ error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
return execution_result;
}
+ else if (execution_result == eExecutionStoppedForDebug)
+ {
+ error_stream.PutCString ("Execution was halted at the first instruction of the expression function because \"debug\" was requested.\n"
+ "Use \"thread return -x\" to return to the state before expression evaluation.");
+ return execution_result;
+ }
else if (execution_result != eExecutionCompleted)
{
error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index fb9522f0dc368..8731fbebd148e 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -492,7 +492,10 @@ public:
}
else
{
- err.SetErrorStringWithFormat("size of variable %s disagrees with the ValueObject's size", m_variable_sp->GetName().AsCString());
+ err.SetErrorStringWithFormat("size of variable %s (%" PRIu64 ") disagrees with the ValueObject's size (%" PRIu64 ")",
+ m_variable_sp->GetName().AsCString(),
+ m_variable_sp->GetType()->GetByteSize(),
+ data.GetByteSize());
}
return;
}