diff options
author | Jim Ingham <jingham@apple.com> | 2013-11-07 00:11:47 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2013-11-07 00:11:47 +0000 |
commit | 6fbc48bc427f4d8368bcb37116843045981e9b76 (patch) | |
tree | 7c1e9f97d44d3c381aa732274ecda09ded4a5287 /lldb/source/Target/ThreadPlanCallFunction.cpp | |
parent | bed356a9eae0d45b878410b5c42d6ff278bb0c83 (diff) | |
download | bcm5719-llvm-6fbc48bc427f4d8368bcb37116843045981e9b76.tar.gz bcm5719-llvm-6fbc48bc427f4d8368bcb37116843045981e9b76.zip |
This patch does a couple of things.
It completes the job of using EvaluateExpressionOptions consistently throughout
the inferior function calling mechanism in lldb begun in Greg's patch r194009.
It removes a handful of alternate calls into the ClangUserExpression/ClangFunction/ThreadPlanCallFunction which
were there for convenience. Using the EvaluateExpressionOptions removes the need for them.
Using that it gets the --debug option from Greg's patch to work cleanly.
It also adds another EvaluateExpressionOption to not trap exceptions when running expressions. You shouldn't
use this option unless you KNOW your expression can't throw beyond itself. This is:
<rdar://problem/15374885>
At present this is only available through the SB API's or python.
It fixes a bug where function calls would unset the ObjC & C++ exception breakpoints without checking whether
they were set by somebody else already.
llvm-svn: 194182
Diffstat (limited to 'lldb/source/Target/ThreadPlanCallFunction.cpp')
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 90 |
1 files changed, 51 insertions, 39 deletions
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; |