https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/207251
liblldb statically absorbs the lldbHost and lldbUtility archives (and every plugin). A tool that links the shared liblldb while also linking those same archives statically ends up with two copies of that object code. On ELF, if the tool re-exports the archive symbols in its own .dynsym, the dynamic linker can bind liblldb's internal references to the tool's copy instead of liblldb's own, breaking shared-state assumptions such as the HostInfo singletons. 106644f6c835 fixed this for the lldb driver with --exclude-libs,ALL, but lldb-dap and lldb-mcp have the same setup and were left exposed. Factor the logic into a shared lldb_prevent_liblldb_symbol_interposition helper and call it from all three tools. >From e489a1a910901807984b938d6aa2b7c50f7f498e Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Thu, 2 Jul 2026 11:48:19 -0700 Subject: [PATCH] [lldb][CMake] Extend liblldb interposition fix to lldb-dap and lldb-mcp liblldb statically absorbs the lldbHost and lldbUtility archives (and every plugin). A tool that links the shared liblldb while also linking those same archives statically ends up with two copies of that object code. On ELF, if the tool re-exports the archive symbols in its own .dynsym, the dynamic linker can bind liblldb's internal references to the tool's copy instead of liblldb's own, breaking shared-state assumptions such as the HostInfo singletons. 106644f6c835 fixed this for the lldb driver with --exclude-libs,ALL, but lldb-dap and lldb-mcp have the same setup and were left exposed. Factor the logic into a shared lldb_prevent_liblldb_symbol_interposition helper and call it from all three tools. --- lldb/cmake/modules/AddLLDB.cmake | 14 ++++++++++++++ lldb/tools/driver/CMakeLists.txt | 11 +---------- lldb/tools/lldb-dap/tool/CMakeLists.txt | 2 ++ lldb/tools/lldb-mcp/CMakeLists.txt | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index 6e56dfd783d1f..5c1a245346f77 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -469,6 +469,20 @@ function(add_lldb_tool name) set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON) endfunction() +# liblldb statically absorbs lldbHost, lldbUtility, and every plugin. A tool +# that links the shared liblldb while also linking those archives statically +# carries a second copy of their object code. On ELF, if the tool re-exports +# the archive symbols through its own .dynsym, the dynamic linker can bind +# liblldb's internal references to the tool's copy instead of its own, breaking +# shared state such as the HostInfo singletons. --exclude-libs,ALL keeps the +# archive symbols out of the tool's .dynsym. Only ELF is affected: Mach-O uses +# two-level namespaces and PE/COFF does not export symbols by default. +function(lldb_prevent_liblldb_symbol_interposition name) + if(UNIX AND NOT APPLE) + target_link_options(${name} PRIVATE "LINKER:--exclude-libs,ALL") + endif() +endfunction() + # The test suite relies on finding LLDB.framework binary resources in the # build-tree. Remove them before installing to avoid collisions with their # own install targets. diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt index 38670a14a78b0..19a1cd7bbcea8 100644 --- a/lldb/tools/driver/CMakeLists.txt +++ b/lldb/tools/driver/CMakeLists.txt @@ -52,16 +52,7 @@ add_dependencies(lldb ${tablegen_deps} ) -# lldbHost and lldbUtility are also statically linked into liblldb.so, so any -# state they carry exists in two independent copies. On ELF platforms this -# creates an interposition hazard: when liblldb.so exports a symbol from those -# archives (e.g. for dynamic plugin loading), the dynamic linker can resolve -# it to lldb's copy instead of liblldb.so's, breaking shared-state assumptions. -# --exclude-libs,ALL keeps archive symbols out of lldb's .dynsym, eliminating -# the hazard without affecting the executable's own use of those symbols. -if(UNIX AND NOT APPLE) - target_link_options(lldb PRIVATE "LINKER:--exclude-libs,ALL") -endif() +lldb_prevent_liblldb_symbol_interposition(lldb) if(LLDB_BUILD_FRAMEWORK) # In the build-tree, we know the exact path to the framework directory. diff --git a/lldb/tools/lldb-dap/tool/CMakeLists.txt b/lldb/tools/lldb-dap/tool/CMakeLists.txt index 33263cb5adb6b..3567e9e6e9394 100644 --- a/lldb/tools/lldb-dap/tool/CMakeLists.txt +++ b/lldb/tools/lldb-dap/tool/CMakeLists.txt @@ -19,6 +19,8 @@ add_dependencies(lldb-dap ${tablegen_deps} ) +lldb_prevent_liblldb_symbol_interposition(lldb-dap) + if(APPLE) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/lldb-dap-Info.plist.in diff --git a/lldb/tools/lldb-mcp/CMakeLists.txt b/lldb/tools/lldb-mcp/CMakeLists.txt index 72b96f2a1f898..ab68f853a0f49 100644 --- a/lldb/tools/lldb-mcp/CMakeLists.txt +++ b/lldb/tools/lldb-mcp/CMakeLists.txt @@ -11,6 +11,8 @@ add_lldb_tool(lldb-mcp lldbProtocolMCP ) +lldb_prevent_liblldb_symbol_interposition(lldb-mcp) + if(APPLE) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/lldb-mcp-Info.plist.in _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
