Compilation can end up calling functions (e.g. to resolve indirect functions) so...
authorJim Ingham <jingham@apple.com>
Mon, 21 Mar 2016 19:21:13 +0000 (19:21 +0000)
committerJim Ingham <jingham@apple.com>
Mon, 21 Mar 2016 19:21:13 +0000 (19:21 +0000)
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

14 files changed:
lldb/include/lldb/Expression/FunctionCaller.h
lldb/include/lldb/Expression/UtilityFunction.h
lldb/include/lldb/Target/ThreadList.h
lldb/source/Expression/FunctionCaller.cpp
lldb/source/Expression/UserExpression.cpp
lldb/source/Expression/UtilityFunction.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp

index 24347b1..3848073 100644 (file)
@@ -99,6 +99,11 @@ public:
     //------------------------------------------------------------------
     /// 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
     ///     The diagnostic manager to report parser errors to.
     ///
@@ -106,7 +111,8 @@ public:
     ///     The number of errors.
     //------------------------------------------------------------------
     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
index ed38fe4..a789720 100644 (file)
@@ -139,8 +139,10 @@ public:
     }
     
     // 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 *
-    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
     FunctionCaller *
index c5dbb19..eec7340 100644 (file)
@@ -62,7 +62,7 @@ public:
         
         ~ExpressionExecutionThreadPusher()
         {
-            if (m_thread_list)
+            if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
                 m_thread_list->PopExpressionExecutionThread(m_tid);
         }
         
index 0590c3b..3a4f1fe 100644 (file)
@@ -232,7 +232,7 @@ bool
 FunctionCaller::InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
                                DiagnosticManager &diagnostic_manager)
 {
-    if (CompileFunction(diagnostic_manager) != 0)
+    if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
         return false;
     if (!WriteFunctionWrapper(exe_ctx, diagnostic_manager))
         return false;
@@ -345,8 +345,8 @@ FunctionCaller::ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_ad
         args_addr = *args_addr_ptr;
     else
         args_addr = LLDB_INVALID_ADDRESS;
-
-    if (CompileFunction(diagnostic_manager) != 0)
+        
+    if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
         return lldb::eExpressionSetupError;
 
     if (args_addr == LLDB_INVALID_ADDRESS)
index 6b97eb6..6f637b1 100644 (file)
@@ -194,6 +194,11 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx,
 
     if (process == NULL || !process->CanJIT())
         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 *option_prefix = options.GetPrefix();
index 7805961..926d580 100644 (file)
@@ -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...
 
 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)
         return m_caller_up.get();
@@ -99,7 +99,7 @@ UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const Valu
     {
         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)
         {
             error.SetErrorStringWithFormat("Error compiling %s caller function: \"%s\".", m_function_name.c_str(),
index a823945..02c0ad5 100644 (file)
@@ -74,11 +74,16 @@ ClangFunctionCaller::~ClangFunctionCaller()
 }
 
 unsigned
-ClangFunctionCaller::CompileFunction(DiagnosticManager &diagnostic_manager)
+
+ClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp, 
+                                      DiagnosticManager &diagnostic_manager)
 {
     if (m_compiled)
         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.
     unsigned num_errors = 0;
     
index f37c3b3..468b9c1 100644 (file)
@@ -137,6 +137,11 @@ public:
     //------------------------------------------------------------------
     /// 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
     ///     The diagnostic manager to report parser errors to.
     ///
@@ -144,7 +149,8 @@ public:
     ///     The number of errors.
     //------------------------------------------------------------------
     unsigned
-    CompileFunction(DiagnosticManager &diagnostic_manager) override;
+    CompileFunction (lldb::ThreadSP thread_to_use_sp,
+                     DiagnosticManager &diagnostic_manager) override;
 
     ExpressionTypeSystemHelper *
     GetTypeSystemHelper() override
index 638b651..4ad5e0c 100644 (file)
@@ -1308,6 +1308,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
         
         get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
                                                                             arguments,
+                                                                            thread_sp,
                                                                             error);
         
         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,
                                                                                                       arguments,
+                                                                                                      thread_sp,
                                                                                                       error);
         
         if (get_shared_cache_class_info_function == nullptr)
index b9994d6..614c267 100644 (file)
@@ -741,9 +741,11 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
 lldb::addr_t
 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;
     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
     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,
                                                                    dispatch_values,
+                                                                   thread_sp,
                                                                    error);
             if (error.Fail())
             {
index 19f89f0..688626e 100644 (file)
@@ -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_arglist,
+                                                                                 thread.shared_from_this(),
                                                                                  error);
             if (error.Fail())
             {
index cda7264..c262ffc 100644 (file)
@@ -139,9 +139,11 @@ AppleGetPendingItemsHandler::Detach ()
 lldb::addr_t
 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;
     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
     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();
             get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
                                                                                           get_pending_items_arglist,
+                                                                                          thread_sp,
                                                                                           error);
             if (error.Fail())
             {
index e005d50..e1f0451 100644 (file)
@@ -147,7 +147,9 @@ AppleGetQueuesHandler::Detach ()
 lldb::addr_t
 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;
     DiagnosticManager diagnostics;
     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
@@ -205,6 +207,7 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
         Error error;
         get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
                                                                        get_queues_arglist,
+                                                                       thread_sp,
                                                                        error);
         if (error.Fail())
         {
index a528daf..266e461 100644 (file)
@@ -142,7 +142,8 @@ AppleGetThreadItemInfoHandler::Detach ()
 lldb::addr_t
 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;
     DiagnosticManager diagnostics;
     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_arglist,
+                                                                                                 thread_sp,
                                                                                                  error);
             if (error.Fail())
             {