Author: Raphael Isemann Date: 2026-07-17T08:14:43+01:00 New Revision: 250f791e7002afb308e4a59dc5ef3e1f2e1c10af
URL: https://github.com/llvm/llvm-project/commit/250f791e7002afb308e4a59dc5ef3e1f2e1c10af DIFF: https://github.com/llvm/llvm-project/commit/250f791e7002afb308e4a59dc5ef3e1f2e1c10af.diff LOG: [lldb] Fix tsan error in SymbolLocatorDebugSymbols (#209698) g_dlsym_DBGCopyFullDSYMURLForUUID and g_dlsym_DBGCopyDSYMPropertyLists are two globals that are lazily initialized when first used. TSan complains that this lazy init code is not thread-safe as there is no synchronization mechanism. In practice, the only race that can happen here is that we initialize the same values concurrently, which should be 'safe' on any platform. This patch moves the initialization code into a static local that returns a const object. This makes this code thread-safe by construction and fixes the TSan error. It also fixes that we keep calling dlopen if the initialization fails. That is, the `g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr` will always be true on systems where the framework doesn't exist, so this code will try loading it on every function call and fail. Added: Modified: lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp index 7c7facfdbd589..aeb6a07298207 100644 --- a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp @@ -53,10 +53,37 @@ using namespace lldb; using namespace lldb_private; -static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)( - CFUUIDRef uuid, CFURLRef exec_url) = nullptr; -static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = - nullptr; +namespace { +struct DebugSymbolsDylibFunctions { + CFURLRef (*DBGCopyFullDSYMURLForUUID)(CFUUIDRef uuid, + CFURLRef exec_url) = nullptr; + CFDictionaryRef (*DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = nullptr; + + DebugSymbolsDylibFunctions() { + void *handle = dlopen( + "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", + RTLD_LAZY | RTLD_LOCAL); + if (handle) { + DBGCopyFullDSYMURLForUUID = (CFURLRef (*)(CFUUIDRef, CFURLRef))dlsym( + handle, "DBGCopyFullDSYMURLForUUID"); + DBGCopyDSYMPropertyLists = (CFDictionaryRef (*)(CFURLRef))dlsym( + handle, "DBGCopyDSYMPropertyLists"); + } + } + + /// Returns true if all DebugSymbols functions were found in the framework. + bool FoundFunctions() const { + return DBGCopyFullDSYMURLForUUID != nullptr && + DBGCopyDSYMPropertyLists != nullptr; + } +}; +} // namespace + +static const DebugSymbolsDylibFunctions &GetDebugSymbolsDylibFunctions() { + // This is a static local to avoid race conditions. + static DebugSymbolsDylibFunctions g_functions; + return g_functions; +} LLDB_PLUGIN_DEFINE(SymbolLocatorDebugSymbols) @@ -98,24 +125,10 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( int items_found = 0; - if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || - g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { - void *handle = dlopen( - "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", - RTLD_LAZY | RTLD_LOCAL); - if (handle) { - g_dlsym_DBGCopyFullDSYMURLForUUID = - (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle, - "DBGCopyFullDSYMURLForUUID"); - g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym( - handle, "DBGCopyDSYMPropertyLists"); - } - } - - if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || - g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + const DebugSymbolsDylibFunctions &dylib_functions = + GetDebugSymbolsDylibFunctions(); + if (!dylib_functions.FoundFunctions()) return {}; - } if (uuid && uuid->IsValid()) { // Try and locate the dSYM file using DebugSymbols first @@ -138,8 +151,9 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( FALSE)); } - CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID( - module_uuid_ref.get(), exec_url.get())); + CFCReleaser<CFURLRef> dsym_url( + dylib_functions.DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), + exec_url.get())); char path[PATH_MAX]; if (dsym_url.get()) { @@ -175,7 +189,7 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( } CFCReleaser<CFDictionaryRef> dict( - g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get())); + dylib_functions.DBGCopyDSYMPropertyLists(dsym_url.get())); CFDictionaryRef uuid_dict = NULL; if (dict.get()) { CFCString uuid_cfstr(uuid->GetAsString().c_str()); @@ -538,24 +552,10 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, int items_found = 0; - if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || - g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { - void *handle = dlopen( - "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", - RTLD_LAZY | RTLD_LOCAL); - if (handle) { - g_dlsym_DBGCopyFullDSYMURLForUUID = - (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle, - "DBGCopyFullDSYMURLForUUID"); - g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym( - handle, "DBGCopyDSYMPropertyLists"); - } - } - - if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || - g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + const DebugSymbolsDylibFunctions &dylib_functions = + GetDebugSymbolsDylibFunctions(); + if (!dylib_functions.FoundFunctions()) return items_found; - } if (uuid && uuid->IsValid()) { // Try and locate the dSYM file using DebugSymbols first @@ -578,8 +578,9 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, FALSE)); } - CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID( - module_uuid_ref.get(), exec_url.get())); + CFCReleaser<CFURLRef> dsym_url( + dylib_functions.DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), + exec_url.get())); char path[PATH_MAX]; if (dsym_url.get()) { @@ -615,7 +616,7 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, } CFCReleaser<CFDictionaryRef> dict( - g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get())); + dylib_functions.DBGCopyDSYMPropertyLists(dsym_url.get())); CFDictionaryRef uuid_dict = NULL; if (dict.get()) { CFCString uuid_cfstr(uuid->GetAsString().c_str()); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
