forked from OSchip/llvm-project
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
This commit is contained in:
parent
bed356a9ea
commit
6fbc48bc42
|
@ -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);
|
||||
|
|
|
@ -226,143 +226,6 @@ public:
|
|||
ValueList &arg_values,
|
||||
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.
|
||||
///
|
||||
|
@ -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,62 +256,10 @@ 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.
|
||||
///
|
||||
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -66,6 +66,12 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsAreSet ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
|
||||
{
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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_run_others;
|
||||
return m_try_others;
|
||||
}
|
||||
|
||||
EvaluateExpressionOptions&
|
||||
SetRunOthers (bool run_others = true)
|
||||
void
|
||||
SetTryAllThreads (bool try_others = true)
|
||||
{
|
||||
m_run_others = run_others;
|
||||
return *this;
|
||||
m_try_others = try_others;
|
||||
}
|
||||
|
||||
bool
|
||||
GetStopOthers () const
|
||||
{
|
||||
return m_stop_others;
|
||||
}
|
||||
|
||||
void
|
||||
SetStopOthers (bool stop_others = true)
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -528,21 +528,6 @@ public:
|
|||
virtual lldb::ThreadPlanSP
|
||||
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.
|
||||
///
|
||||
|
@ -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:
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -133,7 +133,8 @@ typedef enum ExecutionResults
|
|||
eExecutionDiscarded,
|
||||
eExecutionInterrupted,
|
||||
eExecutionHitBreakpoint,
|
||||
eExecutionTimedOut
|
||||
eExecutionTimedOut,
|
||||
eExecutionStoppedForDebug
|
||||
} ExecutionResults;
|
||||
|
||||
typedef enum ObjCRuntimeVersions {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -478,113 +471,24 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_
|
|||
exe_ctx.GetProcessRef().DeallocateMemory(args_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);
|
||||
}
|
||||
|
||||
// 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));
|
||||
if (!call_plan_sp)
|
||||
return eExecutionSetupError;
|
||||
|
||||
// <rdar://problem/12027563> we need to make sure we record the fact that we are running an expression here
|
||||
// otherwise this fact will fail to be recorded when fetching an Objective-C object description
|
||||
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);
|
||||
|
||||
if (log)
|
||||
{
|
||||
if (results != eExecutionCompleted)
|
||||
{
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Execution completed abnormally ==");
|
||||
}
|
||||
else
|
||||
{
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Execution completed normally ==");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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)
|
||||
|
@ -600,17 +504,44 @@ ClangFunction::ExecuteFunction(
|
|||
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);
|
||||
|
||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
||||
|
||||
if (log)
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Executing function ==");
|
||||
|
||||
lldb::ThreadPlanSP call_plan_sp (GetThreadPlanToCallFunction (exe_ctx,
|
||||
args_addr,
|
||||
real_options,
|
||||
errors));
|
||||
if (!call_plan_sp)
|
||||
return eExecutionSetupError;
|
||||
|
||||
// <rdar://problem/12027563> we need to make sure we record the fact that we are running an expression here
|
||||
// otherwise this fact will fail to be recorded when fetching an Objective-C object description
|
||||
if (exe_ctx.GetProcessPtr())
|
||||
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
|
||||
|
||||
return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
|
||||
call_plan_sp,
|
||||
real_options,
|
||||
errors);
|
||||
|
||||
if (log)
|
||||
{
|
||||
if (return_value != eExecutionCompleted)
|
||||
{
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Execution completed abnormally ==");
|
||||
}
|
||||
else
|
||||
{
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Execution completed normally ==");
|
||||
}
|
||||
}
|
||||
|
||||
if (exe_ctx.GetProcessPtr())
|
||||
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
|
||||
|
||||
if (args_addr_ptr != NULL)
|
||||
*args_addr_ptr = args_addr;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -444,6 +444,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)
|
||||
{
|
||||
|
|
|
@ -70,6 +70,9 @@ namespace lldb_private {
|
|||
virtual void
|
||||
ClearExceptionBreakpoints ();
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsAreSet ();
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -361,6 +359,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)
|
||||
{
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
virtual void
|
||||
ClearExceptionBreakpoints ();
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsAreSet ();
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1419,14 +1419,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
|
||||
(
|
||||
|
@ -1469,25 +1461,6 @@ Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_othe
|
|||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue