forked from OSchip/llvm-project
Make the Expression Execution result enum available to the SB API layer.
Add a callback that will allow an expression to be cancelled between the expression evaluation stages (for the ClangUserExpressions.) <rdar://problem/16790467>, <rdar://problem/16573440> llvm-svn: 207944
This commit is contained in:
parent
e8a7afef86
commit
1624a2d3c8
|
@ -86,6 +86,9 @@ public:
|
|||
|
||||
void
|
||||
SetTrapExceptions (bool trap_exceptions = true);
|
||||
|
||||
void
|
||||
SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -209,6 +209,13 @@ public:
|
|||
void
|
||||
SetMachError (uint32_t err);
|
||||
|
||||
|
||||
void
|
||||
SetExpressionError (lldb::ExpressionResults, const char *mssg);
|
||||
|
||||
int
|
||||
SetExpressionErrorWithFormat (lldb::ExpressionResults, const char *format, ...) __attribute__ ((format (printf, 3,4)));
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accesssor with an error value and type.
|
||||
///
|
||||
|
|
|
@ -253,9 +253,9 @@ public:
|
|||
/// The result value will be put here after running the function.
|
||||
///
|
||||
/// @return
|
||||
/// Returns one of the ExecutionResults enum indicating function call status.
|
||||
/// Returns one of the ExpressionResults enum indicating function call status.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
ExecuteFunction(ExecutionContext &exe_ctx,
|
||||
lldb::addr_t *args_addr_ptr,
|
||||
const EvaluateExpressionOptions &options,
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
/// @return
|
||||
/// A Process::Execution results value.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
Execute (Stream &error_stream,
|
||||
ExecutionContext &exe_ctx,
|
||||
const EvaluateExpressionOptions& options,
|
||||
|
@ -296,9 +296,9 @@ public:
|
|||
/// fails to parse, run, or evaluated.
|
||||
///
|
||||
/// @result
|
||||
/// A Process::ExecutionResults value. eExecutionCompleted for success.
|
||||
/// A Process::ExpressionResults value. eExecutionCompleted for success.
|
||||
//------------------------------------------------------------------
|
||||
static ExecutionResults
|
||||
static lldb::ExpressionResults
|
||||
Evaluate (ExecutionContext &exe_ctx,
|
||||
const EvaluateExpressionOptions& options,
|
||||
const char *expr_cstr,
|
||||
|
|
|
@ -2566,14 +2566,14 @@ public:
|
|||
lldb::StateType
|
||||
GetState ();
|
||||
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
RunThreadPlan (ExecutionContext &exe_ctx,
|
||||
lldb::ThreadPlanSP &thread_plan_sp,
|
||||
const EvaluateExpressionOptions &options,
|
||||
Stream &errors);
|
||||
|
||||
static const char *
|
||||
ExecutionResultAsCString (ExecutionResults result);
|
||||
ExecutionResultAsCString (lldb::ExpressionResults result);
|
||||
|
||||
void
|
||||
GetStatus (Stream &ostrm);
|
||||
|
|
|
@ -204,7 +204,9 @@ public:
|
|||
m_generate_debug_info(false),
|
||||
m_use_dynamic(lldb::eNoDynamicValues),
|
||||
m_timeout_usec(default_timeout),
|
||||
m_one_thread_timeout_usec(0)
|
||||
m_one_thread_timeout_usec(0),
|
||||
m_cancel_callback (nullptr),
|
||||
m_cancel_callback_baton (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -377,6 +379,22 @@ public:
|
|||
{
|
||||
m_trap_exceptions = b;
|
||||
}
|
||||
|
||||
void
|
||||
SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton)
|
||||
{
|
||||
m_cancel_callback_baton = baton;
|
||||
m_cancel_callback = callback;
|
||||
}
|
||||
|
||||
bool
|
||||
InvokeCancelCallback (lldb::ExpressionEvaluationPhase phase) const
|
||||
{
|
||||
if (m_cancel_callback == nullptr)
|
||||
return false;
|
||||
else
|
||||
return m_cancel_callback (phase, m_cancel_callback_baton);
|
||||
}
|
||||
|
||||
private:
|
||||
ExecutionPolicy m_execution_policy;
|
||||
|
@ -393,6 +411,8 @@ private:
|
|||
lldb::DynamicValueType m_use_dynamic;
|
||||
uint32_t m_timeout_usec;
|
||||
uint32_t m_one_thread_timeout_usec;
|
||||
lldb::ExpressionCancelCallback m_cancel_callback;
|
||||
void *m_cancel_callback_baton;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -1117,7 +1137,7 @@ public:
|
|||
// we provide a way for expressions to be evaluated from the Target itself.
|
||||
// If an expression is going to be run, then it should have a frame filled
|
||||
// in in th execution context.
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
EvaluateExpression (const char *expression,
|
||||
StackFrame *frame,
|
||||
lldb::ValueObjectSP &result_valobj_sp,
|
||||
|
|
|
@ -199,6 +199,22 @@ namespace lldb {
|
|||
} ReturnStatus;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// The results of expression evaluation:
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum ExpressionResults
|
||||
{
|
||||
eExecutionCompleted = 0,
|
||||
eExecutionSetupError,
|
||||
eExecutionParseError,
|
||||
eExecutionDiscarded,
|
||||
eExecutionInterrupted,
|
||||
eExecutionHitBreakpoint,
|
||||
eExecutionTimedOut,
|
||||
eExecutionResultUnavailable,
|
||||
eExecutionStoppedForDebug
|
||||
} ExpressionResults;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Connection Status Types
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -218,7 +234,8 @@ namespace lldb {
|
|||
eErrorTypeInvalid,
|
||||
eErrorTypeGeneric, ///< Generic errors that can be any value.
|
||||
eErrorTypeMachKernel, ///< Mach kernel error codes.
|
||||
eErrorTypePOSIX ///< POSIX error codes.
|
||||
eErrorTypePOSIX, ///< POSIX error codes.
|
||||
eErrorTypeExpression ///< These are from the ExpressionResults enum.
|
||||
} ErrorType;
|
||||
|
||||
|
||||
|
@ -753,6 +770,21 @@ namespace lldb {
|
|||
eQueueKindSerial,
|
||||
eQueueKindConcurrent
|
||||
} QueueKind;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Expression Evaluation Stages
|
||||
// These are the cancellable stages of expression evaluation, passed to the
|
||||
// expression evaluation callback, so that you can interrupt expression
|
||||
// evaluation at the various points in its lifecycle.
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum ExpressionEvaluationPhase
|
||||
{
|
||||
eExpressionEvaluationParse = 0,
|
||||
eExpressionEvaluationIRGen,
|
||||
eExpressionEvaluationExecution,
|
||||
eExpressionEvaluationComplete
|
||||
} ExpressionEvaluationPhase;
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
|
|
|
@ -123,22 +123,6 @@ typedef enum PathType
|
|||
} PathType;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// We can execute ThreadPlans on one thread with various fall-back modes
|
||||
// (try other threads after timeout, etc.) This enum gives the result of
|
||||
// thread plan executions.
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum ExecutionResults
|
||||
{
|
||||
eExecutionSetupError,
|
||||
eExecutionCompleted,
|
||||
eExecutionDiscarded,
|
||||
eExecutionInterrupted,
|
||||
eExecutionHitBreakpoint,
|
||||
eExecutionTimedOut,
|
||||
eExecutionStoppedForDebug
|
||||
} ExecutionResults;
|
||||
|
||||
typedef enum ObjCRuntimeVersions {
|
||||
eObjC_VersionUnknown = 0,
|
||||
eAppleObjC_V1 = 1,
|
||||
|
|
|
@ -54,32 +54,36 @@ namespace lldb
|
|||
typedef void * thread_arg_t; // Host thread argument type
|
||||
typedef unsigned thread_result_t; // Host thread result type
|
||||
typedef thread_result_t (*thread_func_t)(void *); // Host thread function type
|
||||
typedef void (*LogOutputCallback) (const char *, void *baton);
|
||||
typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace lldb {
|
||||
//----------------------------------------------------------------------
|
||||
// MacOSX Types
|
||||
//----------------------------------------------------------------------
|
||||
typedef ::pthread_mutex_t mutex_t;
|
||||
typedef pthread_cond_t condition_t;
|
||||
typedef pthread_rwlock_t rwlock_t;
|
||||
typedef pthread_t thread_t; // Host thread type
|
||||
typedef pthread_key_t thread_key_t;
|
||||
typedef void * thread_arg_t; // Host thread argument type
|
||||
typedef void * thread_result_t; // Host thread result type
|
||||
typedef void * (*thread_func_t)(void *); // Host thread function type
|
||||
typedef void (*LogOutputCallback) (const char *, void *baton);
|
||||
typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
|
||||
namespace lldb
|
||||
{
|
||||
//----------------------------------------------------------------------
|
||||
// MacOSX Types
|
||||
//----------------------------------------------------------------------
|
||||
typedef ::pthread_mutex_t mutex_t;
|
||||
typedef pthread_cond_t condition_t;
|
||||
typedef pthread_rwlock_t rwlock_t;
|
||||
typedef pthread_t thread_t; // Host thread type
|
||||
typedef pthread_key_t thread_key_t;
|
||||
typedef void * thread_arg_t; // Host thread argument type
|
||||
typedef void * thread_result_t; // Host thread result type
|
||||
typedef void * (*thread_func_t)(void *); // Host thread function type
|
||||
} // namespace lldb
|
||||
|
||||
#endif
|
||||
|
||||
namespace lldb
|
||||
{
|
||||
typedef void (*LogOutputCallback) (const char *, void *baton);
|
||||
typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
|
||||
typedef bool (*ExpressionCancelCallback) (ExpressionEvaluationPhase phase, void *baton);
|
||||
}
|
||||
|
||||
#define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL)
|
||||
#define IS_VALID_LLDB_HOST_THREAD(t) ((t) != LLDB_INVALID_HOST_THREAD)
|
||||
|
||||
|
|
|
@ -149,6 +149,12 @@ SBExpressionOptions::SetTrapExceptions (bool trap_exceptions)
|
|||
m_opaque_ap->SetTrapExceptions (trap_exceptions);
|
||||
}
|
||||
|
||||
void
|
||||
SBExpressionOptions::SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton)
|
||||
{
|
||||
m_opaque_ap->SetCancelCallback (callback, baton);
|
||||
}
|
||||
|
||||
EvaluateExpressionOptions *
|
||||
SBExpressionOptions::get() const
|
||||
{
|
||||
|
|
|
@ -1372,7 +1372,7 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option
|
|||
|
||||
Log *expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
ExecutionResults exe_results = eExecutionSetupError;
|
||||
ExpressionResults exe_results = eExecutionSetupError;
|
||||
SBValue expr_result;
|
||||
|
||||
if (expr == NULL || expr[0] == '\0')
|
||||
|
|
|
@ -2611,7 +2611,7 @@ SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &optio
|
|||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
SBValue expr_result;
|
||||
ExecutionResults exe_results = eExecutionSetupError;
|
||||
ExpressionResults exe_results = eExecutionSetupError;
|
||||
ValueObjectSP expr_value_sp;
|
||||
TargetSP target_sp(GetSP());
|
||||
StackFrame *frame = NULL;
|
||||
|
|
|
@ -317,7 +317,7 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
|
|||
|
||||
ClangExpressionVariableSP result_variable_sp;
|
||||
|
||||
ExecutionResults result_code =
|
||||
ExpressionResults result_code =
|
||||
m_user_expression_sp->Execute(execution_errors,
|
||||
exe_ctx,
|
||||
options,
|
||||
|
|
|
@ -1503,7 +1503,7 @@ protected:
|
|||
options.SetUnwindOnError(true);
|
||||
options.SetUseDynamic(eNoDynamicValues);
|
||||
|
||||
ExecutionResults exe_results = eExecutionSetupError;
|
||||
ExpressionResults exe_results = eExecutionSetupError;
|
||||
exe_results = target->EvaluateExpression (command,
|
||||
frame_sp.get(),
|
||||
return_valobj_sp,
|
||||
|
|
|
@ -1256,7 +1256,7 @@ protected:
|
|||
options.SetTryAllThreads(true);
|
||||
options.SetTimeoutUsec(0);
|
||||
|
||||
ExecutionResults expr_result = target->EvaluateExpression (expr,
|
||||
ExpressionResults expr_result = target->EvaluateExpression (expr,
|
||||
frame,
|
||||
valobj_sp,
|
||||
options);
|
||||
|
|
|
@ -264,6 +264,35 @@ Error::SetMachError (uint32_t err)
|
|||
m_string.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Error::SetExpressionError (lldb::ExpressionResults result, const char *mssg)
|
||||
{
|
||||
m_code = result;
|
||||
m_type = eErrorTypeExpression;
|
||||
m_string = mssg;
|
||||
}
|
||||
|
||||
int
|
||||
Error::SetExpressionErrorWithFormat (lldb::ExpressionResults result, const char *format, ...)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
if (format && format[0])
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
length = SetErrorStringWithVarArg (format, args);
|
||||
va_end (args);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_string.clear();
|
||||
}
|
||||
m_code = result;
|
||||
m_type = eErrorTypeExpression;
|
||||
return length;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Set accesssor for the error value and type.
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -334,7 +334,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
|
|||
|
||||
Error error;
|
||||
using namespace clang;
|
||||
ExecutionResults return_value = eExecutionSetupError;
|
||||
lldb::ExpressionResults return_value = lldb::eExecutionSetupError;
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
|
||||
|
@ -502,7 +502,7 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_
|
|||
exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
|
||||
}
|
||||
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
ClangFunction::ExecuteFunction(
|
||||
ExecutionContext &exe_ctx,
|
||||
lldb::addr_t *args_addr_ptr,
|
||||
|
@ -511,7 +511,7 @@ ClangFunction::ExecuteFunction(
|
|||
Value &results)
|
||||
{
|
||||
using namespace clang;
|
||||
ExecutionResults return_value = eExecutionSetupError;
|
||||
lldb::ExpressionResults return_value = lldb::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.
|
||||
|
@ -528,12 +528,12 @@ ClangFunction::ExecuteFunction(
|
|||
args_addr = LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (CompileFunction(errors) != 0)
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
|
||||
if (args_addr == LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
if (!InsertFunction(exe_ctx, args_addr, errors))
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
}
|
||||
|
||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
||||
|
@ -546,7 +546,7 @@ ClangFunction::ExecuteFunction(
|
|||
real_options,
|
||||
errors));
|
||||
if (!call_plan_sp)
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
|
||||
// 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
|
||||
|
@ -560,7 +560,7 @@ ClangFunction::ExecuteFunction(
|
|||
|
||||
if (log)
|
||||
{
|
||||
if (return_value != eExecutionCompleted)
|
||||
if (return_value != lldb::eExecutionCompleted)
|
||||
{
|
||||
log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
|
||||
}
|
||||
|
@ -576,7 +576,7 @@ ClangFunction::ExecuteFunction(
|
|||
if (args_addr_ptr != NULL)
|
||||
*args_addr_ptr = args_addr;
|
||||
|
||||
if (return_value != eExecutionCompleted)
|
||||
if (return_value != lldb::eExecutionCompleted)
|
||||
return return_value;
|
||||
|
||||
FetchFunctionResults(exe_ctx, args_addr, results);
|
||||
|
@ -584,7 +584,7 @@ ClangFunction::ExecuteFunction(
|
|||
if (args_addr_ptr == NULL)
|
||||
DeallocateFunctionResults(exe_ctx, args_addr);
|
||||
|
||||
return eExecutionCompleted;
|
||||
return lldb::eExecutionCompleted;
|
||||
}
|
||||
|
||||
clang::ASTConsumer *
|
||||
|
|
|
@ -798,7 +798,7 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
|
|||
return true;
|
||||
}
|
||||
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
ClangUserExpression::Execute (Stream &error_stream,
|
||||
ExecutionContext &exe_ctx,
|
||||
const EvaluateExpressionOptions& options,
|
||||
|
@ -819,7 +819,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
|
||||
{
|
||||
error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
}
|
||||
|
||||
lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
|
||||
|
@ -833,7 +833,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (!module || !function)
|
||||
{
|
||||
error_stream.Printf("Supposed to interpret, but nothing is there");
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
}
|
||||
|
||||
Error interpreter_error;
|
||||
|
@ -864,7 +864,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (!interpreter_error.Success())
|
||||
{
|
||||
error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
|
||||
return eExecutionDiscarded;
|
||||
return lldb::eExecutionDiscarded;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -872,7 +872,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (!exe_ctx.HasThreadScope())
|
||||
{
|
||||
error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
}
|
||||
|
||||
Address wrapper_address (m_jit_start_addr);
|
||||
|
@ -894,7 +894,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
shared_ptr_to_me));
|
||||
|
||||
if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
|
||||
lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
|
||||
|
||||
|
@ -907,7 +907,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (exe_ctx.GetProcessPtr())
|
||||
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
|
||||
|
||||
ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
|
||||
lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
|
||||
call_plan_sp,
|
||||
options,
|
||||
error_stream);
|
||||
|
@ -918,7 +918,7 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
if (log)
|
||||
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
|
||||
|
||||
if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
|
||||
if (execution_result == lldb::eExecutionInterrupted || execution_result == lldb::eExecutionHitBreakpoint)
|
||||
{
|
||||
const char *error_desc = NULL;
|
||||
|
||||
|
@ -933,21 +933,23 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
else
|
||||
error_stream.PutCString ("Execution was interrupted.");
|
||||
|
||||
if ((execution_result == eExecutionInterrupted && options.DoesUnwindOnError())
|
||||
|| (execution_result == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
|
||||
if ((execution_result == lldb::eExecutionInterrupted && options.DoesUnwindOnError())
|
||||
|| (execution_result == lldb::eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
|
||||
error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
|
||||
else
|
||||
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.");
|
||||
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)
|
||||
else if (execution_result == lldb::eExecutionStoppedForDebug)
|
||||
{
|
||||
error_stream.PutCString ("Execution was halted at the first instruction of the expression function because \"debug\" was requested.\n"
|
||||
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)
|
||||
else if (execution_result != lldb::eExecutionCompleted)
|
||||
{
|
||||
error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
|
||||
return execution_result;
|
||||
|
@ -956,21 +958,21 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
|
||||
if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
|
||||
{
|
||||
return eExecutionCompleted;
|
||||
return lldb::eExecutionCompleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionResultUnavailable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
|
||||
return eExecutionSetupError;
|
||||
return lldb::eExecutionSetupError;
|
||||
}
|
||||
}
|
||||
|
||||
ExecutionResults
|
||||
lldb::ExpressionResults
|
||||
ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
||||
const EvaluateExpressionOptions& options,
|
||||
const char *expr_cstr,
|
||||
|
@ -983,7 +985,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
|
||||
const lldb::LanguageType language = options.GetLanguage();
|
||||
const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
|
||||
ExecutionResults execution_results = eExecutionSetupError;
|
||||
lldb::ExpressionResults execution_results = lldb::eExecutionSetupError;
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
|
||||
|
@ -1013,6 +1015,13 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
const bool keep_expression_in_memory = true;
|
||||
const bool generate_debug_info = options.GetGenerateDebugInfo();
|
||||
|
||||
if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
|
||||
{
|
||||
error.SetErrorString ("expression interrupted by callback before parse");
|
||||
result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
|
||||
return lldb::eExecutionInterrupted;
|
||||
}
|
||||
|
||||
if (!user_expression_sp->Parse (error_stream,
|
||||
exe_ctx,
|
||||
execution_policy,
|
||||
|
@ -1020,9 +1029,9 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
generate_debug_info))
|
||||
{
|
||||
if (error_stream.GetString().empty())
|
||||
error.SetErrorString ("expression failed to parse, unknown error");
|
||||
error.SetExpressionError (lldb::eExecutionParseError, "expression failed to parse, unknown error");
|
||||
else
|
||||
error.SetErrorString (error_stream.GetString().c_str());
|
||||
error.SetExpressionError (lldb::eExecutionParseError, error_stream.GetString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1035,10 +1044,17 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
|
||||
|
||||
if (error_stream.GetString().empty())
|
||||
error.SetErrorString ("expression needed to run but couldn't");
|
||||
error.SetExpressionError (lldb::eExecutionSetupError, "expression needed to run but couldn't");
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
|
||||
{
|
||||
error.SetExpressionError (lldb::eExecutionInterrupted, "expression interrupted by callback before execution");
|
||||
result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
|
||||
return lldb::eExecutionInterrupted;
|
||||
}
|
||||
|
||||
error_stream.GetString().clear();
|
||||
|
||||
if (log)
|
||||
|
@ -1050,15 +1066,15 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
user_expression_sp,
|
||||
expr_result);
|
||||
|
||||
if (execution_results != eExecutionCompleted)
|
||||
if (execution_results != lldb::eExecutionCompleted)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
|
||||
|
||||
if (error_stream.GetString().empty())
|
||||
error.SetErrorString ("expression failed to execute, unknown error");
|
||||
error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
|
||||
else
|
||||
error.SetErrorString (error_stream.GetString().c_str());
|
||||
error.SetExpressionError (execution_results, error_stream.GetString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1067,7 +1083,8 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
result_valobj_sp = expr_result->GetValueObject();
|
||||
|
||||
if (log)
|
||||
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
|
||||
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
|
||||
result_valobj_sp->GetValueAsCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1080,6 +1097,12 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
|
||||
{
|
||||
error.SetExpressionError (lldb::eExecutionInterrupted, "expression interrupted by callback after complete");
|
||||
return lldb::eExecutionInterrupted;
|
||||
}
|
||||
|
||||
if (result_valobj_sp.get() == NULL)
|
||||
{
|
||||
result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
|
||||
|
|
|
@ -817,7 +817,7 @@ Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::add
|
|||
options.SetKeepInMemory(false);
|
||||
options.SetTryAllThreads(true);
|
||||
|
||||
ExecutionResults expr_result = target->EvaluateExpression(s,
|
||||
ExpressionResults expr_result = target->EvaluateExpression(s,
|
||||
exe_ctx->GetFramePtr(),
|
||||
valobj_sp,
|
||||
options);
|
||||
|
|
|
@ -1456,7 +1456,7 @@ CommandInterpreter::PreprocessCommand (std::string &command)
|
|||
options.SetTryAllThreads(true);
|
||||
options.SetTimeoutUsec(0);
|
||||
|
||||
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
||||
ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
|
||||
exe_ctx.GetFramePtr(),
|
||||
expr_result_valobj_sp,
|
||||
options);
|
||||
|
@ -1499,6 +1499,11 @@ CommandInterpreter::PreprocessCommand (std::string &command)
|
|||
case eExecutionSetupError:
|
||||
error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
|
||||
break;
|
||||
case eExecutionParseError:
|
||||
error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str());
|
||||
break;
|
||||
case eExecutionResultUnavailable:
|
||||
error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str());
|
||||
case eExecutionCompleted:
|
||||
break;
|
||||
case eExecutionDiscarded:
|
||||
|
|
|
@ -144,7 +144,7 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
|
|||
options.SetIgnoreBreakpoints(true);
|
||||
options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
|
||||
|
||||
ExecutionResults results = func.ExecuteFunction (exe_ctx,
|
||||
ExpressionResults results = func.ExecuteFunction (exe_ctx,
|
||||
&wrapper_struct_addr,
|
||||
options,
|
||||
error_stream,
|
||||
|
|
|
@ -1846,7 +1846,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
|
|||
errors.Clear();
|
||||
|
||||
// Run the function
|
||||
ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
|
||||
ExpressionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
|
||||
&m_get_class_info_args,
|
||||
options,
|
||||
errors,
|
||||
|
@ -2096,7 +2096,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
|
|||
errors.Clear();
|
||||
|
||||
// Run the function
|
||||
ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
|
||||
ExpressionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
|
||||
&m_get_shared_cache_class_info_args,
|
||||
options,
|
||||
errors,
|
||||
|
|
|
@ -117,7 +117,7 @@ lldb_private::InferiorCallMmap (Process *process,
|
|||
{
|
||||
ExecutionContext exe_ctx;
|
||||
frame->CalculateExecutionContext (exe_ctx);
|
||||
ExecutionResults result = process->RunThreadPlan (exe_ctx,
|
||||
ExpressionResults result = process->RunThreadPlan (exe_ctx,
|
||||
call_plan_sp,
|
||||
options,
|
||||
error_strm);
|
||||
|
@ -202,7 +202,7 @@ lldb_private::InferiorCallMunmap (Process *process,
|
|||
{
|
||||
ExecutionContext exe_ctx;
|
||||
frame->CalculateExecutionContext (exe_ctx);
|
||||
ExecutionResults result = process->RunThreadPlan (exe_ctx,
|
||||
ExpressionResults result = process->RunThreadPlan (exe_ctx,
|
||||
call_plan_sp,
|
||||
options,
|
||||
error_strm);
|
||||
|
@ -260,7 +260,7 @@ lldb_private::InferiorCall (Process *process,
|
|||
{
|
||||
ExecutionContext exe_ctx;
|
||||
frame->CalculateExecutionContext (exe_ctx);
|
||||
ExecutionResults result = process->RunThreadPlan (exe_ctx,
|
||||
ExpressionResults result = process->RunThreadPlan (exe_ctx,
|
||||
call_plan_sp,
|
||||
options,
|
||||
error_strm);
|
||||
|
|
|
@ -363,13 +363,13 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
|
|||
}
|
||||
|
||||
|
||||
ExecutionResults func_call_ret;
|
||||
ExpressionResults func_call_ret;
|
||||
Value results;
|
||||
func_call_ret = m_get_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
|
||||
if (func_call_ret != eExecutionCompleted || !error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_item_info() for list of queues");
|
||||
return return_value;
|
||||
}
|
||||
|
|
|
@ -368,13 +368,13 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
|
|||
}
|
||||
|
||||
|
||||
ExecutionResults func_call_ret;
|
||||
ExpressionResults func_call_ret;
|
||||
Value results;
|
||||
func_call_ret = m_get_pending_items_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
|
||||
if (func_call_ret != eExecutionCompleted || !error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("Unable to call __introspection_dispatch_queue_get_pending_items(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
log->Printf ("Unable to call __introspection_dispatch_queue_get_pending_items(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_pending_items() for list of queues");
|
||||
return return_value;
|
||||
}
|
||||
|
|
|
@ -367,13 +367,13 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
|
|||
options.SetTryAllThreads (false);
|
||||
thread.CalculateExecutionContext (exe_ctx);
|
||||
|
||||
ExecutionResults func_call_ret;
|
||||
ExpressionResults func_call_ret;
|
||||
Value results;
|
||||
func_call_ret = m_get_queues_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
|
||||
if (func_call_ret != eExecutionCompleted || !error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("Unable to call introspection_get_dispatch_queues(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
log->Printf ("Unable to call introspection_get_dispatch_queues(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
error.SetErrorString ("Unable to call introspection_get_dispatch_queues() for list of queues");
|
||||
return return_value;
|
||||
}
|
||||
|
|
|
@ -366,13 +366,13 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
|
|||
}
|
||||
|
||||
|
||||
ExecutionResults func_call_ret;
|
||||
ExpressionResults func_call_ret;
|
||||
Value results;
|
||||
func_call_ret = m_get_thread_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
|
||||
if (func_call_ret != eExecutionCompleted || !error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("Unable to call __introspection_dispatch_thread_get_item_info(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
log->Printf ("Unable to call __introspection_dispatch_thread_get_item_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
|
||||
error.SetErrorString ("Unable to call __introspection_dispatch_thread_get_item_info() for list of queues");
|
||||
return return_value;
|
||||
}
|
||||
|
|
|
@ -5037,13 +5037,13 @@ Process::SettingsTerminate ()
|
|||
Thread::SettingsTerminate ();
|
||||
}
|
||||
|
||||
ExecutionResults
|
||||
ExpressionResults
|
||||
Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
||||
lldb::ThreadPlanSP &thread_plan_sp,
|
||||
const EvaluateExpressionOptions &options,
|
||||
Stream &errors)
|
||||
{
|
||||
ExecutionResults return_value = eExecutionSetupError;
|
||||
ExpressionResults return_value = eExecutionSetupError;
|
||||
|
||||
if (thread_plan_sp.get() == NULL)
|
||||
{
|
||||
|
@ -5939,7 +5939,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
|
|||
}
|
||||
|
||||
const char *
|
||||
Process::ExecutionResultAsCString (ExecutionResults result)
|
||||
Process::ExecutionResultAsCString (ExpressionResults result)
|
||||
{
|
||||
const char *result_name;
|
||||
|
||||
|
@ -5960,6 +5960,12 @@ Process::ExecutionResultAsCString (ExecutionResults result)
|
|||
case eExecutionSetupError:
|
||||
result_name = "eExecutionSetupError";
|
||||
break;
|
||||
case eExecutionParseError:
|
||||
result_name = "eExecutionParseError";
|
||||
break;
|
||||
case eExecutionResultUnavailable:
|
||||
result_name = "eExecutionResultUnavailable";
|
||||
break;
|
||||
case eExecutionTimedOut:
|
||||
result_name = "eExecutionTimedOut";
|
||||
break;
|
||||
|
|
|
@ -708,7 +708,7 @@ protected:
|
|||
{
|
||||
// We need to make sure the user sees any parse errors in their condition, so we'll hook the
|
||||
// constructor errors up to the debugger's Async I/O.
|
||||
ExecutionResults result_code;
|
||||
ExpressionResults result_code;
|
||||
EvaluateExpressionOptions expr_options;
|
||||
expr_options.SetUnwindOnError(true);
|
||||
expr_options.SetIgnoreBreakpoints(true);
|
||||
|
|
|
@ -1855,7 +1855,7 @@ Target::GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr, const Symbol
|
|||
return target;
|
||||
}
|
||||
|
||||
ExecutionResults
|
||||
ExpressionResults
|
||||
Target::EvaluateExpression
|
||||
(
|
||||
const char *expr_cstr,
|
||||
|
@ -1866,7 +1866,7 @@ Target::EvaluateExpression
|
|||
{
|
||||
result_valobj_sp.reset();
|
||||
|
||||
ExecutionResults execution_results = eExecutionSetupError;
|
||||
ExpressionResults execution_results = eExecutionSetupError;
|
||||
|
||||
if (expr_cstr == NULL || expr_cstr[0] == '\0')
|
||||
return execution_results;
|
||||
|
|
Loading…
Reference in New Issue