Author: xiaobai Date: Wed May 22 16:01:18 2019 New Revision: 361442 URL: http://llvm.org/viewvc/llvm-project?rev=361442&view=rev Log: [Target] Protect Processes' language runtimes map with a mutex
Summary: From what I understand, it's possible for multiple threads to request a specific language runtime (e.g. CPPLanguageRuntime). This leads to a data race. Reviewers: jingham, JDevlieghere, compnerd, clayborg Differential Revision: https://reviews.llvm.org/D62169 Modified: lldb/trunk/include/lldb/Target/Process.h lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=361442&r1=361441&r2=361442&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Wed May 22 16:01:18 2019 @@ -2701,6 +2701,7 @@ protected: bool m_should_detach; /// Should we detach if the process object goes away /// with an explicit call to Kill or Detach? LanguageRuntimeCollection m_language_runtimes; + std::recursive_mutex m_language_runtimes_mutex; InstrumentationRuntimeCollection m_instrumentation_runtimes; std::unique_ptr<NextEventAction> m_next_event_action_up; std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions; Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=361442&r1=361441&r2=361442&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Wed May 22 16:01:18 2019 @@ -660,7 +660,10 @@ void Process::Finalize() { m_image_tokens.clear(); m_memory_cache.Clear(); m_allocated_memory_cache.Clear(); - m_language_runtimes.clear(); + { + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); + m_language_runtimes.clear(); + } m_instrumentation_runtimes.clear(); m_next_event_action_up.reset(); // Clear the last natural stop ID since it has a strong reference to this @@ -1549,6 +1552,7 @@ LanguageRuntime *Process::GetLanguageRun if (m_finalizing) return nullptr; + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); LanguageRuntimeCollection::iterator pos; pos = m_language_runtimes.find(language); if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second)) { @@ -1562,6 +1566,7 @@ LanguageRuntime *Process::GetLanguageRun } CPPLanguageRuntime *Process::GetCPPLanguageRuntime(bool retry_if_null) { + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus, retry_if_null); if (runtime != nullptr && @@ -1571,6 +1576,7 @@ CPPLanguageRuntime *Process::GetCPPLangu } ObjCLanguageRuntime *Process::GetObjCLanguageRuntime(bool retry_if_null) { + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeObjC, retry_if_null); if (runtime != nullptr && runtime->GetLanguageType() == eLanguageTypeObjC) @@ -5604,7 +5610,10 @@ void Process::DidExec() { m_jit_loaders_up.reset(); m_image_tokens.clear(); m_allocated_memory_cache.Clear(); - m_language_runtimes.clear(); + { + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); + m_language_runtimes.clear(); + } m_instrumentation_runtimes.clear(); m_thread_list.DiscardThreadPlans(); m_memory_cache.Clear(true); @@ -5673,14 +5682,17 @@ void Process::ModulesDidLoad(ModuleList // Iterate over a copy of this language runtime list in case the language // runtime ModulesDidLoad somehow causes the language runtime to be // unloaded. - LanguageRuntimeCollection language_runtimes(m_language_runtimes); - for (const auto &pair : language_runtimes) { - // We must check language_runtime_sp to make sure it is not nullptr as we - // might cache the fact that we didn't have a language runtime for a - // language. - LanguageRuntimeSP language_runtime_sp = pair.second; - if (language_runtime_sp) - language_runtime_sp->ModulesDidLoad(module_list); + { + std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex); + LanguageRuntimeCollection language_runtimes(m_language_runtimes); + for (const auto &pair : language_runtimes) { + // We must check language_runtime_sp to make sure it is not nullptr as we + // might cache the fact that we didn't have a language runtime for a + // language. + LanguageRuntimeSP language_runtime_sp = pair.second; + if (language_runtime_sp) + language_runtime_sp->ModulesDidLoad(module_list); + } } // If we don't have an operating system plug-in, try to load one since _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits