diff options
Diffstat (limited to 'lldb/source')
23 files changed, 306 insertions, 413 deletions
diff --git a/lldb/source/API/SBExpressionOptions.cpp b/lldb/source/API/SBExpressionOptions.cpp index 127b0cf13cd..ae1c8f99df3 100644 --- a/lldb/source/API/SBExpressionOptions.cpp +++ b/lldb/source/API/SBExpressionOptions.cpp @@ -104,13 +104,25 @@ SBExpressionOptions::SetTimeoutInMicroSeconds (uint32_t timeout) bool SBExpressionOptions::GetTryAllThreads () const { - return m_opaque_ap->GetRunOthers (); + return m_opaque_ap->GetTryAllThreads (); } void SBExpressionOptions::SetTryAllThreads (bool run_others) { - m_opaque_ap->SetRunOthers (run_others); + m_opaque_ap->SetTryAllThreads (run_others); +} + +bool +SBExpressionOptions::GetTrapExceptions () const +{ + return m_opaque_ap->GetTrapExceptions (); +} + +void +SBExpressionOptions::SetTrapExceptions (bool trap_exceptions) +{ + m_opaque_ap->SetTrapExceptions (trap_exceptions); } EvaluateExpressionOptions * diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp index 17568c28b50..5009e862d84 100644 --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -295,7 +295,7 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); - options.SetRunOthers(true); + options.SetTryAllThreads(true); Error expr_error; diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 6d44f71b8d9..5ca44ff920d 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -363,13 +363,13 @@ CommandObjectExpression::EvaluateExpression bool keep_in_memory = true; EvaluateExpressionOptions options; - options.SetCoerceToId(m_varobj_options.use_objc) - .SetUnwindOnError(m_command_options.unwind_on_error) - .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints) - .SetKeepInMemory(keep_in_memory) - .SetUseDynamic(m_varobj_options.use_dynamic) - .SetRunOthers(m_command_options.try_all_threads) - .SetDebug(m_command_options.debug); + options.SetCoerceToId(m_varobj_options.use_objc); + options.SetUnwindOnError(m_command_options.unwind_on_error); + options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints); + options.SetKeepInMemory(keep_in_memory); + options.SetUseDynamic(m_varobj_options.use_dynamic); + options.SetTryAllThreads(m_command_options.try_all_threads); + options.SetDebug(m_command_options.debug); if (m_command_options.timeout > 0) options.SetTimeoutUsec(m_command_options.timeout); diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index a827e9187f4..e55b2ee4d7d 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -1256,11 +1256,11 @@ protected: // Use expression evaluation to arrive at the address to watch. EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(false) - .SetRunOthers(true) - .SetTimeoutUsec(0); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeoutUsec(0); ExecutionResults expr_result = target->EvaluateExpression (expr, frame, diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp index e00413556cc..136c8c51e66 100644 --- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp +++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp @@ -49,9 +49,9 @@ lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj, return false; EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(true); target->EvaluateExpression(expr.GetData(), stack_frame, @@ -83,10 +83,10 @@ lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj, return false; EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(true); + options.SetUseDynamic(lldb::eDynamicCanRunTarget); target->EvaluateExpression(expr.GetData(), stack_frame, @@ -121,10 +121,10 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, return valobj_sp; EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(true); + options.SetUseDynamic(lldb::eDynamicCanRunTarget); target->EvaluateExpression(expr.GetData(), stack_frame, @@ -158,10 +158,10 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, return valobj_sp; EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(true); + options.SetUseDynamic(lldb::eDynamicCanRunTarget); target->EvaluateExpression(expr.GetData(), stack_frame, diff --git a/lldb/source/DataFormatters/LibCxx.cpp b/lldb/source/DataFormatters/LibCxx.cpp index cdc57f6bd93..21e104602a3 100644 --- a/lldb/source/DataFormatters/LibCxx.cpp +++ b/lldb/source/DataFormatters/LibCxx.cpp @@ -35,10 +35,10 @@ m_options() { if (valobj_sp) Update(); - m_options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + m_options.SetCoerceToId(false); + m_options.SetUnwindOnError(true); + m_options.SetKeepInMemory(true); + m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); } size_t diff --git a/lldb/source/DataFormatters/LibStdcpp.cpp b/lldb/source/DataFormatters/LibStdcpp.cpp index e0f23cc35e3..08e7d584003 100644 --- a/lldb/source/DataFormatters/LibStdcpp.cpp +++ b/lldb/source/DataFormatters/LibStdcpp.cpp @@ -34,10 +34,10 @@ m_options() { if (valobj_sp) Update(); - m_options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + m_options.SetCoerceToId(false); + m_options.SetUnwindOnError(true); + m_options.SetKeepInMemory(true); + m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); } size_t @@ -215,10 +215,10 @@ lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIte { if (valobj_sp) Update(); - m_options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(true) - .SetUseDynamic(lldb::eDynamicCanRunTarget); + m_options.SetCoerceToId(false); + m_options.SetUnwindOnError(true); + m_options.SetKeepInMemory(true); + m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); } bool diff --git a/lldb/source/DataFormatters/NSDictionary.cpp b/lldb/source/DataFormatters/NSDictionary.cpp index 05a5dda39e5..f53004df5c5 100644 --- a/lldb/source/DataFormatters/NSDictionary.cpp +++ b/lldb/source/DataFormatters/NSDictionary.cpp @@ -218,8 +218,10 @@ lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIn StreamString object_fetcher_expr; object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData()); lldb::ValueObjectSP child_sp; + EvaluateExpressionOptions options; + options.SetKeepInMemory(true); m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp, - EvaluateExpressionOptions().SetKeepInMemory(true)); + options); if (child_sp) child_sp->SetName(ConstString(idx_name.GetData())); return child_sp; diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index b37044df9ec..92a07971dbc 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/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,14 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, // Okay, now run the function: - Address wrapper_address (func_addr); + Address wrapper_address (m_jit_start_addr); ThreadPlan *new_plan = new ThreadPlanCallFunction (*thread, wrapper_address, ClangASTType(), args_addr, - stop_others, - unwind_on_error, - ignore_breakpoints, - this_arg, - cmd_arg); + options, + 0, + 0); new_plan->SetIsMasterPlan(true); new_plan->SetOkayToDiscard (false); return new_plan; @@ -479,63 +472,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 +522,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 +542,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/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index e4f2830ba25..8ce9c7e5739 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/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,25 +823,11 @@ 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); lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), wrapper_address, - struct_address, - stop_others, - unwind_on_error, - ignore_breakpoints, + struct_address, + options, (m_needs_object_ptr ? &object_ptr : NULL), ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL), shared_ptr_to_me)); @@ -890,19 +847,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 +870,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/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index ff94e0f6021..b6f34fd1f7f 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -815,7 +815,7 @@ Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::add options.SetCoerceToId(false); options.SetUnwindOnError(true); options.SetKeepInMemory(false); - options.SetRunOthers(true); + options.SetTryAllThreads(true); ExecutionResults expr_result = target->EvaluateExpression(s, exe_ctx->GetFramePtr(), diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 794cc716bda..9757a08b1a2 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -1434,12 +1434,12 @@ CommandInterpreter::PreprocessCommand (std::string &command) ValueObjectSP expr_result_valobj_sp; EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetIgnoreBreakpoints(true) - .SetKeepInMemory(false) - .SetRunOthers(true) - .SetTimeoutUsec(0); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeoutUsec(0); ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), exe_ctx.GetFramePtr(), diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index d18b4c75ae7..f3c2d63729a 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -445,6 +445,12 @@ ItaniumABILanguageRuntime::ClearExceptionBreakpoints () } bool +ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet () +{ + return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled(); +} + +bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason) { if (!m_process) diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index 6b2c437de25..cd0a4b2c15e 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -71,6 +71,9 @@ namespace lldb_private { ClearExceptionBreakpoints (); virtual bool + ExceptionBreakpointsAreSet (); + + virtual bool ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason); virtual lldb::BreakpointResolverSP diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index b21d76ca660..2d2e4058159 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -137,19 +137,17 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS; func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream); - const bool unwind_on_error = true; - const bool try_all_threads = true; - const bool stop_others = true; - const bool ignore_breakpoints = true; + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(true); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC); ExecutionResults results = func.ExecuteFunction (exe_ctx, - &wrapper_struct_addr, + &wrapper_struct_addr, + options, error_stream, - stop_others, - PO_FUNCTION_TIMEOUT_USEC /* 15 secs timeout */, - try_all_threads, - unwind_on_error, - ignore_breakpoints, ret); if (results != eExecutionCompleted) { @@ -362,6 +360,12 @@ AppleObjCRuntime::ClearExceptionBreakpoints () } bool +AppleObjCRuntime::ExceptionBreakpointsAreSet () +{ + return m_objc_exception_bp_sp && m_objc_exception_bp_sp->IsEnabled(); +} + +bool AppleObjCRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason) { if (!m_process) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index d198351a6fc..96e98740e1d 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -95,6 +95,9 @@ public: ClearExceptionBreakpoints (); virtual bool + ExceptionBreakpointsAreSet (); + + virtual bool ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason); virtual lldb::SearchFilterSP diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index e16c530329c..f92b86412bf 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -1829,10 +1829,12 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table arguments, errors)) { - bool stop_others = true; - bool try_all_threads = false; - bool unwind_on_error = true; - bool ignore_breakpoints = true; + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(false); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC); Value return_value; return_value.SetValueType (Value::eValueTypeScalar); @@ -1845,12 +1847,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table // Run the function ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx, &m_get_class_info_args, + options, errors, - stop_others, - UTILITY_FUNCTION_TIMEOUT_USEC, - try_all_threads, - unwind_on_error, - ignore_breakpoints, return_value); if (results == eExecutionCompleted) @@ -2080,10 +2078,12 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() arguments, errors)) { - bool stop_others = true; - bool try_all_threads = false; - bool unwind_on_error = true; - bool ignore_breakpoints = true; + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(false); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC); Value return_value; return_value.SetValueType (Value::eValueTypeScalar); @@ -2096,12 +2096,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() // Run the function ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx, &m_get_shared_cache_class_info_args, + options, errors, - stop_others, - UTILITY_FUNCTION_TIMEOUT_USEC, - try_all_threads, - unwind_on_error, - ignore_breakpoints, return_value); if (results == eExecutionCompleted) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index 16d6e2e7d66..2b56e2208d6 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -84,15 +84,15 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction () } m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction(); ExecutionContext exc_ctx; - const bool unwind_on_error = true; - const bool ignore_breakpoints = true; + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetStopOthers(m_stop_others); m_thread.CalculateExecutionContext(exc_ctx); m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, - errors, - m_stop_others, - unwind_on_error, - ignore_breakpoints)); + options, + errors)); m_func_sp->SetOkayToDiscard(true); m_thread.QueueThreadPlan (m_func_sp, false); } diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 8b22d6457ad..4428f372413 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -59,11 +59,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, { const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; const bool use_inline_block_range = false; - const bool stop_other_threads = true; - const bool unwind_on_error = true; - const bool ignore_breakpoints = true; - const bool try_all_threads = true; - const uint32_t timeout_usec = 500000; + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug (false); + options.SetTimeoutUsec(500000); addr_t prot_arg, flags_arg = 0; if (prot == eMmapProtNone) @@ -92,9 +94,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, = new ThreadPlanCallFunction (*thread, mmap_range.GetBaseAddress(), clang_void_ptr_type, - stop_other_threads, - unwind_on_error, - ignore_breakpoints, + options, &addr, &length, &prot_arg, @@ -115,12 +115,8 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, ExecutionContext exe_ctx; frame->CalculateExecutionContext (exe_ctx); ExecutionResults result = process->RunThreadPlan (exe_ctx, - call_plan_sp, - stop_other_threads, - try_all_threads, - unwind_on_error, - ignore_breakpoints, - timeout_usec, + call_plan_sp, + options, error_strm); if (result == eExecutionCompleted) { @@ -169,56 +165,52 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, SymbolContext sc; if (sc_list.GetContextAtIndex(0, sc)) { - const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = false; - const bool stop_other_threads = true; - const bool unwind_on_error = true; - const bool ignore_breakpoints = true; - const bool try_all_threads = true; - const uint32_t timeout_usec = 500000; + const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = false; + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug (false); + options.SetTimeoutUsec(500000); - AddressRange munmap_range; - if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) - { - lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, + AddressRange munmap_range; + if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) + { + lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, munmap_range.GetBaseAddress(), ClangASTType(), - stop_other_threads, - unwind_on_error, - ignore_breakpoints, + options, &addr, &length)); - if (call_plan_sp) - { - StreamFile error_strm; - // This plan is a utility plan, so set it to discard itself when done. - call_plan_sp->SetIsMasterPlan (true); - call_plan_sp->SetOkayToDiscard(true); + if (call_plan_sp) + { + StreamFile error_strm; + // This plan is a utility plan, so set it to discard itself when done. + call_plan_sp->SetIsMasterPlan (true); + call_plan_sp->SetOkayToDiscard(true); - StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); - if (frame) - { - ExecutionContext exe_ctx; - frame->CalculateExecutionContext (exe_ctx); - ExecutionResults result = process->RunThreadPlan (exe_ctx, - call_plan_sp, - stop_other_threads, - try_all_threads, - unwind_on_error, - ignore_breakpoints, - timeout_usec, - error_strm); - if (result == eExecutionCompleted) - { - return true; - } - } - } - } - } - } + StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); + if (frame) + { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext (exe_ctx); + ExecutionResults result = process->RunThreadPlan (exe_ctx, + call_plan_sp, + options, + error_strm); + if (result == eExecutionCompleted) + { + return true; + } + } + } + } + } + } - return false; + return false; } bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) { @@ -226,11 +218,13 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t if (thread == NULL || address == NULL) return false; - const bool stop_other_threads = true; - const bool unwind_on_error = true; - const bool ignore_breakpoints = true; - const bool try_all_threads = true; - const uint32_t timeout_usec = 500000; + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug (false); + options.SetTimeoutUsec(500000); ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); @@ -238,9 +232,7 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t = new ThreadPlanCallFunction (*thread, *address, clang_void_ptr_type, - stop_other_threads, - unwind_on_error, - ignore_breakpoints); + options); lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); if (call_plan_sp) { @@ -256,11 +248,7 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t frame->CalculateExecutionContext (exe_ctx); ExecutionResults result = process->RunThreadPlan (exe_ctx, call_plan_sp, - stop_other_threads, - try_all_threads, - unwind_on_error, - ignore_breakpoints, - timeout_usec, + options, error_strm); if (result == eExecutionCompleted) { diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 700afdb7981..c3d1795611b 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4697,11 +4697,7 @@ Process::SettingsTerminate () ExecutionResults Process::RunThreadPlan (ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, - bool stop_others, - bool run_others, - bool unwind_on_error, - bool ignore_breakpoints, - uint32_t timeout_usec, + const EvaluateExpressionOptions &options, Stream &errors) { ExecutionResults return_value = eExecutionSetupError; @@ -4812,6 +4808,17 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, thread->QueueThreadPlan(thread_plan_sp, false); // This used to pass "true" does that make sense? + if (options.GetDebug()) + { + // In this case, we aren't actually going to run, we just want to stop right away. + // Flush this thread so we will refetch the stacks and show the correct backtrace. + // FIXME: To make this prettier we should invent some stop reason for this, but that + // is only cosmetic, and this functionality is only of use to lldb developers who can + // live with not pretty... + thread->Flush(); + return eExecutionStoppedForDebug; + } + Listener listener("lldb.process.listener.run-thread-plan"); lldb::EventSP event_to_broadcast_sp; @@ -4853,11 +4860,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, TimeValue one_thread_timeout = TimeValue::Now(); TimeValue final_timeout = one_thread_timeout; - if (run_others) + uint32_t timeout_usec = options.GetTimeoutUsec(); + if (options.GetTryAllThreads()) { // If we are running all threads then we take half the time to run all threads, bounded by // .25 sec. - if (timeout_usec == 0) + if (options.GetTimeoutUsec() == 0) one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec); else { @@ -4969,7 +4977,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (before_first_timeout) { - if (run_others) + if (options.GetTryAllThreads()) timeout_ptr = &one_thread_timeout; else { @@ -5085,7 +5093,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (log) log->Printf ("Process::RunThreadPlan() stopped for breakpoint: %s.", stop_info_sp->GetDescription()); return_value = eExecutionHitBreakpoint; - if (!ignore_breakpoints) + if (!options.DoesIgnoreBreakpoints()) { event_to_broadcast_sp = event_sp; } @@ -5094,7 +5102,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { if (log) log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete."); - if (!unwind_on_error) + if (!options.DoesUnwindOnError()) event_to_broadcast_sp = event_sp; return_value = eExecutionInterrupted; } @@ -5145,7 +5153,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // either exit, or try with all threads running for the same timeout. if (log) { - if (run_others) + if (options.GetTryAllThreads()) { uint64_t remaining_time = final_timeout - TimeValue::Now(); if (before_first_timeout) @@ -5228,7 +5236,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, continue; } - if (!run_others) + if (!options.GetTryAllThreads()) { if (log) log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting."); @@ -5301,8 +5309,8 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // 1) The execution successfully completed // 2) We hit a breakpoint, and ignore_breakpoints was true // 3) We got some other error, and discard_on_error was true - bool should_unwind = (return_value == eExecutionInterrupted && unwind_on_error) - || (return_value == eExecutionHitBreakpoint && ignore_breakpoints); + bool should_unwind = (return_value == eExecutionInterrupted && options.DoesUnwindOnError()) + || (return_value == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()); if (return_value == eExecutionCompleted || should_unwind) @@ -5422,7 +5430,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (log) log->PutCString("Process::RunThreadPlan(): execution set up error."); - if (unwind_on_error) + if (options.DoesUnwindOnError()) { thread->DiscardThreadPlansUpToPlan (thread_plan_sp); thread_plan_sp->SetPrivate (orig_plan_private); @@ -5446,7 +5454,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { if (log) log->PutCString("Process::RunThreadPlan(): thread plan stopped in mid course"); - if (unwind_on_error && thread_plan_sp) + if (options.DoesUnwindOnError() && thread_plan_sp) { if (log) log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause unwind_on_error is set."); @@ -5518,6 +5526,9 @@ Process::ExecutionResultAsCString (ExecutionResults result) case eExecutionTimedOut: result_name = "eExecutionTimedOut"; break; + case eExecutionStoppedForDebug: + result_name = "eExecutionStoppedForDebug"; + break; } return result_name; } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 98c26019b4a..316860e5258 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -1420,14 +1420,6 @@ Thread::QueueThreadPlanForStepInRange ThreadPlanSP -Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans) -{ - ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); - QueueThreadPlan (thread_plan_sp, abort_other_plans); - return thread_plan_sp; -} - -ThreadPlanSP Thread::QueueThreadPlanForStepOut ( bool abort_other_plans, @@ -1470,25 +1462,6 @@ Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_othe } ThreadPlanSP -Thread::QueueThreadPlanForCallFunction (bool abort_other_plans, - Address& function, - lldb::addr_t arg, - bool stop_other_threads, - bool unwind_on_error, - bool ignore_breakpoints) -{ - ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, - function, - ClangASTType(), - arg, - stop_other_threads, - unwind_on_error, - ignore_breakpoints)); - QueueThreadPlan (thread_plan_sp, abort_other_plans); - return thread_plan_sp; -} - -ThreadPlanSP Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, Address &target_addr, bool stop_other_threads) diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index c9baaafffd6..87f6de3abe3 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -55,8 +55,6 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread, if (!abi) return false; - TargetSP target_sp (thread.CalculateTarget()); - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); SetBreakpoints(); @@ -74,7 +72,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread, return false; } - Module *exe_module = target_sp->GetExecutableModulePointer(); + Module *exe_module = GetTarget().GetExecutableModulePointer(); if (exe_module == NULL) { @@ -107,7 +105,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread, } } - start_load_addr = m_start_addr.GetLoadAddress (target_sp.get()); + start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); // Checkpoint the thread state so we can restore it later. if (log && log->GetVerbose()) @@ -120,7 +118,7 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread, log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } - function_load_addr = m_function_addr.GetLoadAddress (target_sp.get()); + function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); return true; } @@ -129,28 +127,30 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, const Address &function, const ClangASTType &return_type, addr_t arg, - bool stop_other_threads, - bool unwind_on_error, - bool ignore_breakpoints, + const EvaluateExpressionOptions &options, addr_t *this_arg, addr_t *cmd_arg) : ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), m_valid (false), - m_stop_other_threads (stop_other_threads), + m_stop_other_threads (options.GetStopOthers()), + m_unwind_on_error (options.DoesUnwindOnError()), + m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), + m_debug_execution (options.GetDebug()), + m_trap_exceptions (options.GetTrapExceptions()), m_function_addr (function), m_function_sp (0), m_return_type (return_type), m_takedown_done (false), - m_stop_address (LLDB_INVALID_ADDRESS), - m_unwind_on_error (unwind_on_error), - m_ignore_breakpoints (ignore_breakpoints) + m_should_clear_objc_exception_bp(false), + m_should_clear_cxx_exception_bp (false), + m_stop_address (LLDB_INVALID_ADDRESS) { lldb::addr_t start_load_addr; ABI *abi; lldb::addr_t function_load_addr; if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) return; - + if (this_arg && cmd_arg) { if (!abi->PrepareTrivialCall (thread, @@ -191,9 +191,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, const Address &function, const ClangASTType &return_type, - bool stop_other_threads, - bool unwind_on_error, - bool ignore_breakpoints, + const EvaluateExpressionOptions &options, addr_t *arg1_ptr, addr_t *arg2_ptr, addr_t *arg3_ptr, @@ -202,14 +200,16 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, addr_t *arg6_ptr) : ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), m_valid (false), - m_stop_other_threads (stop_other_threads), + m_stop_other_threads (options.GetStopOthers()), + m_unwind_on_error (options.DoesUnwindOnError()), + m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), + m_debug_execution (options.GetDebug()), + m_trap_exceptions (options.GetTrapExceptions()), m_function_addr (function), m_function_sp (0), m_return_type (return_type), m_takedown_done (false), - m_stop_address (LLDB_INVALID_ADDRESS), - m_unwind_on_error (unwind_on_error), - m_ignore_breakpoints (ignore_breakpoints) + m_stop_address (LLDB_INVALID_ADDRESS) { lldb::addr_t start_load_addr; ABI *abi; @@ -560,25 +560,34 @@ void ThreadPlanCallFunction::SetBreakpoints () { ProcessSP process_sp (m_thread.CalculateProcess()); - if (process_sp) + if (m_trap_exceptions && process_sp) { m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); if (m_cxx_language_runtime) + { + m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); m_cxx_language_runtime->SetExceptionBreakpoints(); + } if (m_objc_language_runtime) + { + m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet(); m_objc_language_runtime->SetExceptionBreakpoints(); + } } } void ThreadPlanCallFunction::ClearBreakpoints () { - if (m_cxx_language_runtime) - m_cxx_language_runtime->ClearExceptionBreakpoints(); - if (m_objc_language_runtime) - m_objc_language_runtime->ClearExceptionBreakpoints(); + if (m_trap_exceptions) + { + if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) + m_cxx_language_runtime->ClearExceptionBreakpoints(); + if (m_objc_language_runtime && m_should_clear_objc_exception_bp) + m_objc_language_runtime->ClearExceptionBreakpoints(); + } } bool @@ -586,21 +595,24 @@ ThreadPlanCallFunction::BreakpointsExplainStop() { StopInfoSP stop_info_sp = GetPrivateStopInfo (); - if ((m_cxx_language_runtime && - m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) - ||(m_objc_language_runtime && - m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) + if (m_trap_exceptions) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); - - SetPlanComplete(false); - - // If the user has set the ObjC language breakpoint, it would normally get priority over our internal - // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. - stop_info_sp->OverrideShouldStop (true); - return true; + if ((m_cxx_language_runtime && + m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) + ||(m_objc_language_runtime && + m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) + { + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); + + SetPlanComplete(false); + + // If the user has set the ObjC language breakpoint, it would normally get priority over our internal + // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. + stop_info_sp->OverrideShouldStop (true); + return true; + } } return false; diff --git a/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 70de1cbe86e..b55526184b7 100644 --- a/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -39,13 +39,11 @@ using namespace lldb_private; ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread, Address &function, lldb::addr_t arg, - bool stop_other_threads, - bool unwind_on_error, - bool ignore_breakpoints, + const EvaluateExpressionOptions &options, lldb::addr_t *this_arg, lldb::addr_t *cmd_arg, ClangUserExpression::ClangUserExpressionSP &user_expression_sp) : - ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, unwind_on_error, ignore_breakpoints, this_arg, cmd_arg), + ThreadPlanCallFunction (thread, function, ClangASTType(), arg, options, this_arg, cmd_arg), m_user_expression_sp (user_expression_sp) { // User expressions are generally "User generated" so we should set them up to stop when done. |

