diff options
Diffstat (limited to 'source/Expression')
-rw-r--r-- | source/Expression/ClangFunction.cpp | 158 | ||||
-rw-r--r-- | source/Expression/ClangUserExpression.cpp | 89 | ||||
-rw-r--r-- | source/Expression/Materializer.cpp | 5 |
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; } |