summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2013-11-07 00:11:47 +0000
committerJim Ingham <jingham@apple.com>2013-11-07 00:11:47 +0000
commit6fbc48bc427f4d8368bcb37116843045981e9b76 (patch)
tree7c1e9f97d44d3c381aa732274ecda09ded4a5287
parentbed356a9eae0d45b878410b5c42d6ff278bb0c83 (diff)
downloadbcm5719-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
-rw-r--r--lldb/include/lldb/API/SBExpressionOptions.h6
-rw-r--r--lldb/include/lldb/Expression/ClangFunction.h223
-rw-r--r--lldb/include/lldb/Expression/ClangUserExpression.h4
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h6
-rw-r--r--lldb/include/lldb/Target/Process.h6
-rw-r--r--lldb/include/lldb/Target/Target.h70
-rw-r--r--lldb/include/lldb/Target/Thread.h23
-rw-r--r--lldb/include/lldb/Target/ThreadPlanCallFunction.h16
-rw-r--r--lldb/include/lldb/Target/ThreadPlanCallUserExpression.h4
-rw-r--r--lldb/include/lldb/lldb-private-enumerations.h3
-rw-r--r--lldb/scripts/Python/interface/SBExpressionOptions.i7
-rw-r--r--lldb/source/API/SBExpressionOptions.cpp16
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp14
-rw-r--r--lldb/source/Commands/CommandObjectWatchpoint.cpp10
-rw-r--r--lldb/source/DataFormatters/CXXFormatterFunctions.cpp30
-rw-r--r--lldb/source/DataFormatters/LibCxx.cpp8
-rw-r--r--lldb/source/DataFormatters/LibStdcpp.cpp16
-rw-r--r--lldb/source/DataFormatters/NSDictionary.cpp4
-rw-r--r--lldb/source/Expression/ClangFunction.cpp155
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp76
-rw-r--r--lldb/source/Interpreter/Args.cpp2
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp12
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h3
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp24
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h3
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp32
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp12
-rw-r--r--lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp128
-rw-r--r--lldb/source/Target/Process.cpp43
-rw-r--r--lldb/source/Target/Thread.cpp27
-rw-r--r--lldb/source/Target/ThreadPlanCallFunction.cpp90
-rw-r--r--lldb/source/Target/ThreadPlanCallUserExpression.cpp6
-rw-r--r--lldb/test/expression_command/call-throws/TestCallThatThrows.py11
-rw-r--r--lldb/test/expression_command/call-throws/call-throws.m17
36 files changed, 415 insertions, 700 deletions
diff --git a/lldb/include/lldb/API/SBExpressionOptions.h b/lldb/include/lldb/API/SBExpressionOptions.h
index eed9ed528be..6a3a640432f 100644
--- a/lldb/include/lldb/API/SBExpressionOptions.h
+++ b/lldb/include/lldb/API/SBExpressionOptions.h
@@ -65,6 +65,12 @@ public:
void
SetTryAllThreads (bool run_others = true);
+ bool
+ GetTrapExceptions () const;
+
+ void
+ SetTrapExceptions (bool trap_exceptions = true);
+
protected:
SBExpressionOptions (lldb_private::EvaluateExpressionOptions &expression_options);
diff --git a/lldb/include/lldb/Expression/ClangFunction.h b/lldb/include/lldb/Expression/ClangFunction.h
index 9cb22ed15cb..da9b4f822b1 100644
--- a/lldb/include/lldb/Expression/ClangFunction.h
+++ b/lldb/include/lldb/Expression/ClangFunction.h
@@ -227,143 +227,6 @@ public:
Stream &errors);
//------------------------------------------------------------------
- /// [Static] Execute a function, passing it a single void* parameter.
- /// ClangFunction uses this to call the wrapper function.
- ///
- /// @param[in] exe_ctx
- /// The execution context to insert the function and its arguments
- /// into.
- ///
- /// @param[in] function_address
- /// The address of the function in the target process.
- ///
- /// @param[in] void_arg
- /// The value of the void* parameter.
- ///
- /// @param[in] stop_others
- /// True if other threads should pause during execution.
- ///
- /// @param[in] try_all_threads
- /// If the timeout expires, true if other threads should run. If
- /// the function may try to take locks, this is useful.
- ///
- /// @param[in] unwind_on_error
- /// If true, and the execution stops before completion, we unwind the
- /// function call, and return the program state to what it was before the
- /// execution. If false, we leave the program in the stopped state.
- ///
- /// @param[in] timeout_usec
- /// Timeout value (0 for no timeout). If try_all_threads is true, then we
- /// will try on one thread for the lesser of .25 sec and half the total timeout.
- /// then switch to running all threads, otherwise this will be the total timeout.
- ///
- /// @param[in] errors
- /// The stream to write errors to.
- ///
- /// @param[in] this_arg
- /// If non-NULL, the function is invoked like a C++ method, with the
- /// value pointed to by the pointer as its 'this' argument.
- ///
- /// @return
- /// Returns one of the ExecutionResults enum indicating function call status.
- //------------------------------------------------------------------
- static ExecutionResults
- 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 = 0);
-
- //------------------------------------------------------------------
- /// Run the function this ClangFunction was created with.
- ///
- /// This simple version will run the function stopping other threads
- /// for a fixed timeout period (1000 usec) and if it does not complete,
- /// we halt the process and try with all threads running.
- ///
- /// @param[in] exe_ctx
- /// The thread & process in which this function will run.
- ///
- /// @param[in] errors
- /// Errors will be written here if there are any.
- ///
- /// @param[out] results
- /// The result value will be put here after running the function.
- ///
- /// @return
- /// Returns one of the ExecutionResults enum indicating function call status.
- //------------------------------------------------------------------
- ExecutionResults
- ExecuteFunction(ExecutionContext &exe_ctx,
- Stream &errors,
- Value &results);
-
- //------------------------------------------------------------------
- /// Run the function this ClangFunction was created with.
- ///
- /// This simple version will run the function obeying the stop_others
- /// argument. There is no timeout.
- ///
- /// @param[in] exe_ctx
- /// The thread & process in which this function will run.
- ///
- /// @param[in] errors
- /// Errors will be written here if there are any.
- ///
- /// @param[in] stop_others
- /// If \b true, run only this thread, if \b false let all threads run.
- ///
- /// @param[out] results
- /// The result value will be put here after running the function.
- ///
- /// @return
- /// Returns one of the ExecutionResults enum indicating function call status.
- //------------------------------------------------------------------
- ExecutionResults
- ExecuteFunction(ExecutionContext &exe_ctx,
- Stream &errors, bool stop_others,
- Value &results);
-
- //------------------------------------------------------------------
- /// Run the function this ClangFunction was created with.
- ///
- /// This simple version will run the function on one thread. If \a timeout_usec
- /// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will
- /// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned.
- ///
- /// @param[in] exe_ctx
- /// The thread & process in which this function will run.
- ///
- /// @param[in] errors
- /// Errors will be written here if there are any.
- ///
- /// @param[in] timeout_usec
- /// Timeout value (0 for no timeout). If try_all_threads is true, then we
- /// will try on one thread for the lesser of .25 sec and half the total timeout.
- /// then switch to running all threads, otherwise this will be the total timeout.
- ///
- /// @param[in] try_all_threads
- /// If \b true, run only this thread, if \b false let all threads run.
- ///
- /// @param[out] results
- /// The result value will be put here after running the function.
- ///
- /// @return
- /// Returns one of the ExecutionResults enum indicating function call status.
- //------------------------------------------------------------------
- ExecutionResults
- ExecuteFunction(ExecutionContext &exe_ctx,
- Stream &errors,
- uint32_t single_thread_timeout_usec,
- bool try_all_threads,
- Value &results);
-
- //------------------------------------------------------------------
/// Run the function this ClangFunction was created with.
///
/// This is the full version.
@@ -381,17 +244,8 @@ public:
/// @param[in] errors
/// Errors will be written here if there are any.
///
- /// @param[in] stop_others
- /// If \b true, run only this thread, if \b false let all threads run.
- ///
- /// @param[in] timeout_usec
- /// Timeout value (0 for no timeout). If try_all_threads is true, then we
- /// will try on one thread for the lesser of .25 sec and half the total timeout.
- /// then switch to running all threads, otherwise this will be the total timeout.
- ///
- ///
- /// @param[in] try_all_threads
- /// If \b true, run only this thread, if \b false let all threads run.
+ /// @param[in] options
+ /// The options for this expression execution.
///
/// @param[out] results
/// The result value will be put here after running the function.
@@ -402,63 +256,11 @@ public:
ExecutionResults
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,
+ const EvaluateExpressionOptions &options,
+ Stream &errors,
Value &results);
//------------------------------------------------------------------
- /// [static] Get a thread plan to run a function.
- ///
- /// @param[in] exe_ctx
- /// The execution context to insert the function and its arguments
- /// into.
- ///
- /// @param[in] func_addr
- /// The address of the function in the target process.
- ///
- /// @param[in] args_addr_ref
- /// The value of the void* parameter.
- ///
- /// @param[in] errors
- /// The stream to write errors to.
- ///
- /// @param[in] stop_others
- /// True if other threads should pause during execution.
- ///
- /// @param[in] unwind_on_error
- /// True if the thread plan may simply be discarded if an error occurs.
- ///
- /// @param[in] ignore_breakpoints
- /// True if the expression execution will ignore breakpoint hits and continue executing.
- ///
- /// @param[in] this_arg
- /// If non-NULL (and cmd_arg is NULL), the function is invoked like a C++
- /// method, with the value pointed to by the pointer as its 'this'
- /// argument.
- ///
- /// @param[in] cmd_arg
- /// If non-NULL, the function is invoked like an Objective-C method, with
- /// this_arg in the 'self' slot and cmd_arg in the '_cmd' slot
- ///
- /// @return
- /// A ThreadPlan for executing the function.
- //------------------------------------------------------------------
- static ThreadPlan *
- GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t func_addr,
- lldb::addr_t &args_addr_ref,
- Stream &errors,
- bool stop_others,
- bool unwind_on_error,
- bool ignore_breakpoints,
- lldb::addr_t *this_arg = 0,
- lldb::addr_t *cmd_arg = 0);
-
- //------------------------------------------------------------------
/// Get a thread plan to run the function this ClangFunction was created with.
///
/// @param[in] exe_ctx
@@ -485,20 +287,9 @@ public:
//------------------------------------------------------------------
ThreadPlan *
GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors,
- bool stop_others,
- bool unwind_on_error = true,
- bool ignore_breakpoints = true)
- {
- return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
- m_jit_start_addr,
- args_addr_ref,
- errors,
- stop_others,
- unwind_on_error,
- ignore_breakpoints);
- }
+ lldb::addr_t &args_addr_ref,
+ const EvaluateExpressionOptions &options,
+ Stream &errors);
//------------------------------------------------------------------
/// Get the result of the function from its struct
diff --git a/lldb/include/lldb/Expression/ClangUserExpression.h b/lldb/include/lldb/Expression/ClangUserExpression.h
index b8c3c128acf..83fdf1c2195 100644
--- a/lldb/include/lldb/Expression/ClangUserExpression.h
+++ b/lldb/include/lldb/Expression/ClangUserExpression.h
@@ -150,10 +150,6 @@ public:
ClangUserExpressionSP &shared_ptr_to_me,
lldb::ClangExpressionVariableSP &result);
- ThreadPlan *
- GetThreadPlanToExecuteJITExpression (Stream &error_stream,
- ExecutionContext &exe_ctx);
-
//------------------------------------------------------------------
/// Apply the side effects of the function to program state.
///
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 93c0437da75..0aaa67c2382 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -67,6 +67,12 @@ public:
}
virtual bool
+ ExceptionBreakpointsAreSet ()
+ {
+ return false;
+ }
+
+ virtual bool
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
{
return false;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index b55b8da1352..c8979f02d31 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2502,11 +2502,7 @@ public:
ExecutionResults
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);
static const char *
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 1c90ea6f15e..793b6e533d5 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -189,8 +189,10 @@ public:
m_unwind_on_error(true),
m_ignore_breakpoints (false),
m_keep_in_memory(false),
- m_run_others(true),
+ m_try_others(true),
+ m_stop_others(true),
m_debug(false),
+ m_trap_exceptions(true),
m_use_dynamic(lldb::eNoDynamicValues),
m_timeout_usec(default_timeout)
{}
@@ -201,11 +203,10 @@ public:
return m_execution_policy;
}
- EvaluateExpressionOptions&
+ void
SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
{
m_execution_policy = policy;
- return *this;
}
lldb::LanguageType
@@ -214,11 +215,10 @@ public:
return m_language;
}
- EvaluateExpressionOptions&
+ void
SetLanguage(lldb::LanguageType language)
{
m_language = language;
- return *this;
}
bool
@@ -227,11 +227,10 @@ public:
return m_coerce_to_id;
}
- EvaluateExpressionOptions&
+ void
SetCoerceToId (bool coerce = true)
{
m_coerce_to_id = coerce;
- return *this;
}
bool
@@ -240,11 +239,10 @@ public:
return m_unwind_on_error;
}
- EvaluateExpressionOptions&
+ void
SetUnwindOnError (bool unwind = false)
{
m_unwind_on_error = unwind;
- return *this;
}
bool
@@ -253,11 +251,10 @@ public:
return m_ignore_breakpoints;
}
- EvaluateExpressionOptions&
+ void
SetIgnoreBreakpoints (bool ignore = false)
{
m_ignore_breakpoints = ignore;
- return *this;
}
bool
@@ -266,11 +263,10 @@ public:
return m_keep_in_memory;
}
- EvaluateExpressionOptions&
+ void
SetKeepInMemory (bool keep = true)
{
m_keep_in_memory = keep;
- return *this;
}
lldb::DynamicValueType
@@ -279,11 +275,10 @@ public:
return m_use_dynamic;
}
- EvaluateExpressionOptions&
+ void
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
{
m_use_dynamic = dynamic;
- return *this;
}
uint32_t
@@ -292,24 +287,34 @@ public:
return m_timeout_usec;
}
- EvaluateExpressionOptions&
+ void
SetTimeoutUsec (uint32_t timeout = 0)
{
m_timeout_usec = timeout;
- return *this;
}
bool
- GetRunOthers () const
+ GetTryAllThreads () const
+ {
+ return m_try_others;
+ }
+
+ void
+ SetTryAllThreads (bool try_others = true)
+ {
+ m_try_others = try_others;
+ }
+
+ bool
+ GetStopOthers () const
{
- return m_run_others;
+ return m_stop_others;
}
- EvaluateExpressionOptions&
- SetRunOthers (bool run_others = true)
+ void
+ SetStopOthers (bool stop_others = true)
{
- m_run_others = run_others;
- return *this;
+ m_stop_others = stop_others;
}
bool
@@ -318,11 +323,22 @@ public:
return m_debug;
}
- EvaluateExpressionOptions&
+ void
SetDebug(bool b)
{
m_debug = b;
- return *this;
+ }
+
+ bool
+ GetTrapExceptions() const
+ {
+ return m_trap_exceptions;
+ }
+
+ void
+ SetTrapExceptions (bool b)
+ {
+ m_trap_exceptions = b;
}
private:
@@ -332,8 +348,10 @@ private:
bool m_unwind_on_error;
bool m_ignore_breakpoints;
bool m_keep_in_memory;
- bool m_run_others;
+ bool m_try_others;
+ bool m_stop_others;
bool m_debug;
+ bool m_trap_exceptions;
lldb::DynamicValueType m_use_dynamic;
uint32_t m_timeout_usec;
};
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index 7dac37caa20..bc4b1176deb 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -529,21 +529,6 @@ public:
QueueFundamentalPlan (bool abort_other_plans);
//------------------------------------------------------------------
- /// Queues the plan used to step over a breakpoint at the current PC of \a thread.
- /// The default version returned by Process handles trap based breakpoints, and
- /// will disable the breakpoint, single step over it, then re-enable it.
- ///
- /// @param[in] abort_other_plans
- /// \b true if we discard the currently queued plans and replace them with this one.
- /// Otherwise this plan will go on the end of the plan stack.
- ///
- /// @return
- /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
- //------------------------------------------------------------------
- virtual lldb::ThreadPlanSP
- QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans);
-
- //------------------------------------------------------------------
/// Queues the plan used to step one instruction from the current PC of \a thread.
///
/// @param[in] step_over
@@ -728,14 +713,6 @@ public:
bool stop_others,
uint32_t frame_idx);
- virtual lldb::ThreadPlanSP
- QueueThreadPlanForCallFunction (bool abort_other_plans,
- Address& function,
- lldb::addr_t arg,
- bool stop_other_threads,
- bool unwind_on_error = false,
- bool ignore_breakpoints = true);
-
//------------------------------------------------------------------
// Thread Plan accessors:
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/lldb/include/lldb/Target/ThreadPlanCallFunction.h
index 7b8efb60b88..2cf9f82f28c 100644
--- a/lldb/include/lldb/Target/ThreadPlanCallFunction.h
+++ b/lldb/include/lldb/Target/ThreadPlanCallFunction.h
@@ -30,18 +30,14 @@ public:
const Address &function,
const ClangASTType &return_type,
lldb::addr_t arg,
- bool stop_other_threads,
- bool unwind_on_error = true,
- bool ignore_breakpoints = false,
+ const EvaluateExpressionOptions &options,
lldb::addr_t *this_arg = 0,
lldb::addr_t *cmd_arg = 0);
ThreadPlanCallFunction (Thread &thread,
const Address &function,
const ClangASTType &return_type,
- bool stop_other_threads,
- bool unwind_on_error,
- bool ignore_breakpoints,
+ const EvaluateExpressionOptions &options,
lldb::addr_t *arg1_ptr = NULL,
lldb::addr_t *arg2_ptr = NULL,
lldb::addr_t *arg3_ptr = NULL,
@@ -171,6 +167,10 @@ private:
bool m_valid;
bool m_stop_other_threads;
+ bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
+ bool m_debug_execution;
+ bool m_trap_exceptions;
Address m_function_addr;
Address m_start_addr;
lldb::addr_t m_function_sp;
@@ -187,9 +187,9 @@ private:
ClangASTType m_return_type;
lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer, use the ABI to extract values when complete
bool m_takedown_done; // We want to ensure we only do the takedown once. This ensures that.
+ bool m_should_clear_objc_exception_bp;
+ bool m_should_clear_cxx_exception_bp;
lldb::addr_t m_stop_address; // This is the address we stopped at. Also set in DoTakedown;
- bool m_unwind_on_error;
- bool m_ignore_breakpoints;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction);
};
diff --git a/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h b/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h
index 7a7ec33049e..e86096d4048 100644
--- a/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h
+++ b/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h
@@ -28,9 +28,7 @@ public:
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);
diff --git a/lldb/include/lldb/lldb-private-enumerations.h b/lldb/include/lldb/lldb-private-enumerations.h
index e523b912eac..98919422be5 100644
--- a/lldb/include/lldb/lldb-private-enumerations.h
+++ b/lldb/include/lldb/lldb-private-enumerations.h
@@ -133,7 +133,8 @@ typedef enum ExecutionResults
eExecutionDiscarded,
eExecutionInterrupted,
eExecutionHitBreakpoint,
- eExecutionTimedOut
+ eExecutionTimedOut,
+ eExecutionStoppedForDebug
} ExecutionResults;
typedef enum ObjCRuntimeVersions {
diff --git a/lldb/scripts/Python/interface/SBExpressionOptions.i b/lldb/scripts/Python/interface/SBExpressionOptions.i
index 703d51c8483..06b9be310de 100644
--- a/lldb/scripts/Python/interface/SBExpressionOptions.i
+++ b/lldb/scripts/Python/interface/SBExpressionOptions.i
@@ -71,6 +71,13 @@ public:
void
SetTryAllThreads (bool run_others = true);
+ bool
+ GetTrapExceptions () const;
+
+ %feature("docstring", "Sets whether to abort expression evaluation if an exception is thrown while executing. Don't set this to false unless you know the function you are calling traps all exceptions itself.") SetTryAllThreads;
+ void
+ SetTrapExceptions (bool trap_exceptions = true);
+
protected:
SBExpressionOptions (lldb_private::EvaluateExpressionOptions &expression_options);
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.
diff --git a/lldb/test/expression_command/call-throws/TestCallThatThrows.py b/lldb/test/expression_command/call-throws/TestCallThatThrows.py
index 8a849b322b9..5902857508d 100644
--- a/lldb/test/expression_command/call-throws/TestCallThatThrows.py
+++ b/lldb/test/expression_command/call-throws/TestCallThatThrows.py
@@ -98,6 +98,17 @@ class ExprCommandWithThrowTestCase(TestBase):
self.assertTrue (value.IsValid() and value.GetError().Success() == False)
self.check_after_call()
+
+ # Now turn off exception trapping, and call a function that catches the exceptions,
+ # and make sure the function actually completes, and we get the right value:
+ options.SetTrapExceptions(False)
+ value = frame.EvaluateExpression ("[my_class iCatchMyself]", options)
+ self.assertTrue (value.IsValid())
+ self.assertTrue (value.GetError().Success() == True)
+ self.assertTrue (value.GetValueAsUnsigned() == 57)
+ self.check_after_call()
+ options.SetTrapExceptions(True)
+
# Now set this unwind on error to false, and make sure that we stop where the exception was thrown
options.SetUnwindOnError(False)
value = frame.EvaluateExpression ("[my_class callMeIThrow]", options)
diff --git a/lldb/test/expression_command/call-throws/call-throws.m b/lldb/test/expression_command/call-throws/call-throws.m
index c19902278ee..a184718be7d 100644
--- a/lldb/test/expression_command/call-throws/call-throws.m
+++ b/lldb/test/expression_command/call-throws/call-throws.m
@@ -4,6 +4,7 @@
{
}
- (int) callMeIThrow;
+- (int) iCatchMyself;
@end
@implementation MyClass
@@ -16,6 +17,20 @@
@throw e;
return 56;
}
+
+- (int) iCatchMyself
+{
+ int return_value = 55;
+ @try
+ {
+ return_value = [self callMeIThrow];
+ }
+ @catch (NSException *e)
+ {
+ return_value = 57;
+ }
+ return return_value;
+}
@end
int
@@ -26,7 +41,7 @@ main ()
NSLog (@"I am about to throw.");
- return_value = [my_class callMeIThrow];
+ return_value = [my_class iCatchMyself];
return return_value;
}
OpenPOWER on IntegriCloud