From 7837a1b5b5d4a7009b3cf59a7b0d35b8a0ca7400 Mon Sep 17 00:00:00 2001 From: jimingham Date: Fri, 2 May 2025 11:51:21 -0700 Subject: [PATCH] Don't hold the Target's ModuleListLock over running LoadScriptingResourceInTarget (#138216) That calls an unknown amount of Python code, and can do quite a bit of work - especially if people do things like launch scripted processes in this script affordance. Doing that while holding a major lock like the ModuleList lock is asking for trouble. I tried to make a test that would actually stall without this, but I couldn't come up with anything that reliably failed. You always have to get pretty unlucky. (cherry picked from commit 0ddcd209ddc8956eb52d642937a4397c6b08449c) --- lldb/source/Core/ModuleList.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 1df9b945d404d..de2d1528cebbf 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -1304,8 +1304,14 @@ bool ModuleList::LoadScriptingResourcesInTarget(Target *target, bool continue_on_error) { if (!target) return false; - std::lock_guard guard(m_modules_mutex); - for (auto module : m_modules) { + m_modules_mutex.lock(); + // Don't hold the module list mutex while loading the scripting resources, + // The initializer might do any amount of work, and having that happen while + // the module list is held is asking for A/B locking problems. + const ModuleList tmp_module_list(*this); + m_modules_mutex.unlock(); + + for (auto module : tmp_module_list.ModulesNoLocking()) { if (module) { Status error; if (!module->LoadScriptingResourceInTarget(target, error,