diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 5d8db6b4e5e64..a131416cef4a8 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -104,6 +104,7 @@ static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain +static llvm::ThreadPool *g_thread_pool = nullptr; static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = { { @@ -538,6 +539,7 @@ void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) { "Debugger::Initialize called more than once!"); g_debugger_list_mutex_ptr = new std::recursive_mutex(); g_debugger_list_ptr = new DebuggerList(); + g_thread_pool = new llvm::ThreadPool(llvm::optimal_concurrency()); g_load_plugin_callback = load_plugin_callback; } @@ -545,6 +547,11 @@ void Debugger::Terminate() { assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!"); + if (g_thread_pool) { + // The destructor will wait for all the threads to complete. + delete g_thread_pool; + } + if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { // Clear our global list of debugger objects { @@ -2005,11 +2012,7 @@ Status Debugger::RunREPL(LanguageType language, const char *repl_options) { } llvm::ThreadPool &Debugger::GetThreadPool() { - // NOTE: intentional leak to avoid issues with C++ destructor chain - static llvm::ThreadPool *g_thread_pool = nullptr; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - g_thread_pool = new llvm::ThreadPool(llvm::optimal_concurrency()); - }); + assert(g_thread_pool && + "Debugger::GetThreadPool called before Debugger::Initialize"); return *g_thread_pool; }