forked from OSchip/llvm-project
Compilation can end up calling functions (e.g. to resolve indirect functions) so I added
a way for compilation to take a "thread to use for compilation". If it isn't set then the compilation will use the currently selected thread. This should help keep function execution to the one thread intended. llvm-svn: 263972
This commit is contained in:
parent
cdaf644c48
commit
6896b35585
|
@ -99,6 +99,11 @@ public:
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Compile the wrapper function
|
/// Compile the wrapper function
|
||||||
///
|
///
|
||||||
|
/// @param[in] thread_to_use_sp
|
||||||
|
/// Compilation might end up calling functions. Pass in the thread you
|
||||||
|
/// want the compilation to use. If you pass in an empty ThreadSP it will
|
||||||
|
/// use the currently selected thread.
|
||||||
|
///
|
||||||
/// @param[in] diagnostic_manager
|
/// @param[in] diagnostic_manager
|
||||||
/// The diagnostic manager to report parser errors to.
|
/// The diagnostic manager to report parser errors to.
|
||||||
///
|
///
|
||||||
|
@ -106,7 +111,8 @@ public:
|
||||||
/// The number of errors.
|
/// The number of errors.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
virtual unsigned
|
virtual unsigned
|
||||||
CompileFunction(DiagnosticManager &diagnostic_manager) = 0;
|
CompileFunction (lldb::ThreadSP thread_to_use_sp,
|
||||||
|
DiagnosticManager &diagnostic_manager) = 0;
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Insert the default function wrapper and its default argument struct
|
/// Insert the default function wrapper and its default argument struct
|
||||||
|
|
|
@ -139,8 +139,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// This makes the function caller function.
|
// This makes the function caller function.
|
||||||
|
// Pass in the ThreadSP if you have one available, compilation can end up calling code (e.g. to look up indirect
|
||||||
|
// functions) and we don't want this to wander onto another thread.
|
||||||
FunctionCaller *
|
FunctionCaller *
|
||||||
MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error);
|
MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP compilation_thread, Error &error);
|
||||||
|
|
||||||
// This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr
|
// This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr
|
||||||
FunctionCaller *
|
FunctionCaller *
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
~ExpressionExecutionThreadPusher()
|
~ExpressionExecutionThreadPusher()
|
||||||
{
|
{
|
||||||
if (m_thread_list)
|
if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
|
||||||
m_thread_list->PopExpressionExecutionThread(m_tid);
|
m_thread_list->PopExpressionExecutionThread(m_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ bool
|
||||||
FunctionCaller::InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
|
FunctionCaller::InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
|
||||||
DiagnosticManager &diagnostic_manager)
|
DiagnosticManager &diagnostic_manager)
|
||||||
{
|
{
|
||||||
if (CompileFunction(diagnostic_manager) != 0)
|
if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
|
||||||
return false;
|
return false;
|
||||||
if (!WriteFunctionWrapper(exe_ctx, diagnostic_manager))
|
if (!WriteFunctionWrapper(exe_ctx, diagnostic_manager))
|
||||||
return false;
|
return false;
|
||||||
|
@ -345,8 +345,8 @@ FunctionCaller::ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_ad
|
||||||
args_addr = *args_addr_ptr;
|
args_addr = *args_addr_ptr;
|
||||||
else
|
else
|
||||||
args_addr = LLDB_INVALID_ADDRESS;
|
args_addr = LLDB_INVALID_ADDRESS;
|
||||||
|
|
||||||
if (CompileFunction(diagnostic_manager) != 0)
|
if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
|
||||||
return lldb::eExpressionSetupError;
|
return lldb::eExpressionSetupError;
|
||||||
|
|
||||||
if (args_addr == LLDB_INVALID_ADDRESS)
|
if (args_addr == LLDB_INVALID_ADDRESS)
|
||||||
|
|
|
@ -194,6 +194,11 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
|
||||||
|
|
||||||
if (process == NULL || !process->CanJIT())
|
if (process == NULL || !process->CanJIT())
|
||||||
execution_policy = eExecutionPolicyNever;
|
execution_policy = eExecutionPolicyNever;
|
||||||
|
|
||||||
|
// We need to set the expression execution thread here, turns out parse can call functions in the process of
|
||||||
|
// looking up symbols, which will escape the context set by exe_ctx passed to Execute.
|
||||||
|
lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
|
||||||
|
ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_sp);
|
||||||
|
|
||||||
const char *full_prefix = NULL;
|
const char *full_prefix = NULL;
|
||||||
const char *option_prefix = options.GetPrefix();
|
const char *option_prefix = options.GetPrefix();
|
||||||
|
|
|
@ -70,7 +70,7 @@ UtilityFunction::~UtilityFunction ()
|
||||||
// FIXME: We should check that every time this is called it is called with the same return type & arguments...
|
// FIXME: We should check that every time this is called it is called with the same return type & arguments...
|
||||||
|
|
||||||
FunctionCaller *
|
FunctionCaller *
|
||||||
UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, Error &error)
|
UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP thread_to_use_sp, Error &error)
|
||||||
{
|
{
|
||||||
if (m_caller_up)
|
if (m_caller_up)
|
||||||
return m_caller_up.get();
|
return m_caller_up.get();
|
||||||
|
@ -99,7 +99,7 @@ UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const Valu
|
||||||
{
|
{
|
||||||
DiagnosticManager diagnostics;
|
DiagnosticManager diagnostics;
|
||||||
|
|
||||||
unsigned num_errors = m_caller_up->CompileFunction(diagnostics);
|
unsigned num_errors = m_caller_up->CompileFunction(thread_to_use_sp, diagnostics);
|
||||||
if (num_errors)
|
if (num_errors)
|
||||||
{
|
{
|
||||||
error.SetErrorStringWithFormat("Error compiling %s caller function: \"%s\".", m_function_name.c_str(),
|
error.SetErrorStringWithFormat("Error compiling %s caller function: \"%s\".", m_function_name.c_str(),
|
||||||
|
|
|
@ -74,11 +74,16 @@ ClangFunctionCaller::~ClangFunctionCaller()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
ClangFunctionCaller::CompileFunction(DiagnosticManager &diagnostic_manager)
|
|
||||||
|
ClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp,
|
||||||
|
DiagnosticManager &diagnostic_manager)
|
||||||
{
|
{
|
||||||
if (m_compiled)
|
if (m_compiled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Compilation might call code, make sure to keep on the thread the caller indicated.
|
||||||
|
ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_to_use_sp);
|
||||||
|
|
||||||
// FIXME: How does clang tell us there's no return value? We need to handle that case.
|
// FIXME: How does clang tell us there's no return value? We need to handle that case.
|
||||||
unsigned num_errors = 0;
|
unsigned num_errors = 0;
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,11 @@ public:
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Compile the wrapper function
|
/// Compile the wrapper function
|
||||||
///
|
///
|
||||||
|
/// @param[in] thread_to_use_sp
|
||||||
|
/// Compilation might end up calling functions. Pass in the thread you
|
||||||
|
/// want the compilation to use. If you pass in an empty ThreadSP it will
|
||||||
|
/// use the currently selected thread.
|
||||||
|
///
|
||||||
/// @param[in] diagnostic_manager
|
/// @param[in] diagnostic_manager
|
||||||
/// The diagnostic manager to report parser errors to.
|
/// The diagnostic manager to report parser errors to.
|
||||||
///
|
///
|
||||||
|
@ -144,7 +149,8 @@ public:
|
||||||
/// The number of errors.
|
/// The number of errors.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
unsigned
|
unsigned
|
||||||
CompileFunction(DiagnosticManager &diagnostic_manager) override;
|
CompileFunction (lldb::ThreadSP thread_to_use_sp,
|
||||||
|
DiagnosticManager &diagnostic_manager) override;
|
||||||
|
|
||||||
ExpressionTypeSystemHelper *
|
ExpressionTypeSystemHelper *
|
||||||
GetTypeSystemHelper() override
|
GetTypeSystemHelper() override
|
||||||
|
|
|
@ -1308,6 +1308,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
|
||||||
|
|
||||||
get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
|
get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
|
||||||
arguments,
|
arguments,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
|
@ -1567,6 +1568,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
|
||||||
|
|
||||||
get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
|
get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
|
||||||
arguments,
|
arguments,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (get_shared_cache_class_info_function == nullptr)
|
if (get_shared_cache_class_info_function == nullptr)
|
||||||
|
|
|
@ -741,9 +741,11 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
|
||||||
lldb::addr_t
|
lldb::addr_t
|
||||||
AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values)
|
AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values)
|
||||||
{
|
{
|
||||||
ExecutionContext exe_ctx(thread.shared_from_this());
|
ThreadSP thread_sp(thread.shared_from_this());
|
||||||
|
ExecutionContext exe_ctx (thread_sp);
|
||||||
DiagnosticManager diagnostics;
|
DiagnosticManager diagnostics;
|
||||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
||||||
|
|
||||||
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
|
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
|
||||||
FunctionCaller *impl_function_caller = nullptr;
|
FunctionCaller *impl_function_caller = nullptr;
|
||||||
|
|
||||||
|
@ -795,6 +797,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dis
|
||||||
|
|
||||||
impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
|
impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
|
||||||
dispatch_values,
|
dispatch_values,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
{
|
{
|
||||||
|
|
|
@ -189,6 +189,7 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction(Thread &thread, ValueList &get
|
||||||
|
|
||||||
get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
|
get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
|
||||||
get_item_info_arglist,
|
get_item_info_arglist,
|
||||||
|
thread.shared_from_this(),
|
||||||
error);
|
error);
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,9 +139,11 @@ AppleGetPendingItemsHandler::Detach ()
|
||||||
lldb::addr_t
|
lldb::addr_t
|
||||||
AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueList &get_pending_items_arglist)
|
AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueList &get_pending_items_arglist)
|
||||||
{
|
{
|
||||||
ExecutionContext exe_ctx(thread.shared_from_this());
|
ThreadSP thread_sp (thread.shared_from_this());
|
||||||
|
ExecutionContext exe_ctx (thread_sp);
|
||||||
DiagnosticManager diagnostics;
|
DiagnosticManager diagnostics;
|
||||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
||||||
|
|
||||||
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
|
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
|
||||||
FunctionCaller *get_pending_items_caller = nullptr;
|
FunctionCaller *get_pending_items_caller = nullptr;
|
||||||
|
|
||||||
|
@ -191,6 +193,7 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueL
|
||||||
CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
|
CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
|
||||||
get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
|
get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
|
||||||
get_pending_items_arglist,
|
get_pending_items_arglist,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,7 +147,9 @@ AppleGetQueuesHandler::Detach ()
|
||||||
lldb::addr_t
|
lldb::addr_t
|
||||||
AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
|
AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
|
||||||
{
|
{
|
||||||
ExecutionContext exe_ctx(thread.shared_from_this());
|
ThreadSP thread_sp(thread.shared_from_this());
|
||||||
|
ExecutionContext exe_ctx (thread_sp);
|
||||||
|
|
||||||
Address impl_code_address;
|
Address impl_code_address;
|
||||||
DiagnosticManager diagnostics;
|
DiagnosticManager diagnostics;
|
||||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
||||||
|
@ -205,6 +207,7 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
|
||||||
Error error;
|
Error error;
|
||||||
get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
|
get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
|
||||||
get_queues_arglist,
|
get_queues_arglist,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,7 +142,8 @@ AppleGetThreadItemInfoHandler::Detach ()
|
||||||
lldb::addr_t
|
lldb::addr_t
|
||||||
AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
|
AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
|
||||||
{
|
{
|
||||||
ExecutionContext exe_ctx(thread.shared_from_this());
|
ThreadSP thread_sp(thread.shared_from_this());
|
||||||
|
ExecutionContext exe_ctx (thread_sp);
|
||||||
Address impl_code_address;
|
Address impl_code_address;
|
||||||
DiagnosticManager diagnostics;
|
DiagnosticManager diagnostics;
|
||||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
|
||||||
|
@ -199,6 +200,7 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
|
||||||
|
|
||||||
get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
|
get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
|
||||||
get_thread_item_info_arglist,
|
get_thread_item_info_arglist,
|
||||||
|
thread_sp,
|
||||||
error);
|
error);
|
||||||
if (error.Fail())
|
if (error.Fail())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue