Author: Yuval Deutscher Date: 2025-04-22T11:43:23+02:00 New Revision: a86f4ee774e6d2eb9f38502ddda65842179a246a
URL: https://github.com/llvm/llvm-project/commit/a86f4ee774e6d2eb9f38502ddda65842179a246a DIFF: https://github.com/llvm/llvm-project/commit/a86f4ee774e6d2eb9f38502ddda65842179a246a.diff LOG: [lldb] Use correct path for debugserver (#131609) This solves an issue that arises when running lldb-server through a symlink which is not named exactly `lldb-server`. For example, in many distros lldb-server is packaged as e.g. `/usr/lib/llvm-19/bin/lldb-server` which is then accessed through a symlink such as `/usr/bin/lldb-server-19`. It turns out that there is a cascade of bugs here: * `GetShlibDir` attempts to locate the LLVM library directory by calling `GetModuleFileSpecForHostAddress` on the address of the function `ComputeSharedLibraryDirectory`, assuming that it is inside `liblldb.so`. However, in every packaging I've seen of lldb-server the function `ComputeSharedLibraryDirectory` is statically linked into the `lldb-server` binary and is not in `liblldb.so`. * When run through a symlink, `GetModuleFileSpecForHostAddress` on an address that is in `lldb-server` returns the path of the symlink, not the path of the binary itself. So we get e.g. `/usr/bin/` and not `/usr/lib/llvm-19/bin/`. * `GetDebugserverPath` attempts to concat `"lldb-server"` to the directory we obtained, and thus fails when the symlink is not named exactly `lldb-server`. * Ironically, the reason that this works in the first place is precisely because `GetModuleFileSpecForHostAddress` returns an incorrect path - when the server is run as `lldb-server-19 ...` it returns `"lldb-server-19"` which then causes `ComputePathRelativeToLibrary` to fail and then `ComputeSupportExeDirectory` falls back to just using `GetProgramFileSpec` instead (which is the only option that actually yields a correct path). Added: Modified: lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py lldb/tools/lldb-server/SystemInitializerLLGS.h Removed: ################################################################################ diff --git a/lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py b/lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py index c365bc993e338..ea846149e4983 100644 --- a/lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py +++ b/lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py @@ -58,3 +58,42 @@ def test_platform_process_launch_gdb_server(self): self.runCmd("target create {}".format(self.getBuildArtifact("a.out"))) self.expect("run", substrs=["unable to launch a GDB server on"], error=True) + + @skipIfRemote + @skipUnlessPlatform(["linux"]) + @add_test_categories(["lldb-server"]) + def test_lldb_server_weird_symlinks(self): + self.build() + + hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] + listen_url = "[%s]:0" % hostname + + port_file = self.getBuildArtifact("port") + commandline_args = [ + "platform", + "--listen", + listen_url, + "--socket-file", + port_file, + ] + + # Run lldb-server from a symlink without any binary called "lldb-server" in the directory. + new_lldb_server = self.getBuildArtifact( + "lldb-server-with-an-unconventional-name" + ) + os.symlink(lldbgdbserverutils.get_lldb_server_exe(), new_lldb_server) + + proc = self.spawnSubprocess(new_lldb_server, commandline_args) + socket_id = lldbutil.wait_for_file_on_target(self, port_file) + + new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) + self.dbg.SetSelectedPlatform(new_platform) + + connect_url = "connect://[%s]:%s" % (hostname, socket_id) + self.runCmd("platform connect %s" % connect_url) + self.runCmd("target create {}".format(self.getBuildArtifact("a.out"))) + self.runCmd("run") + self.expect( + "process status", + patterns=["Process .* exited with status = 0"], + ) diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.h b/lldb/tools/lldb-server/SystemInitializerLLGS.h index 4469a8ba5f60a..c6020b0dd37da 100644 --- a/lldb/tools/lldb-server/SystemInitializerLLGS.h +++ b/lldb/tools/lldb-server/SystemInitializerLLGS.h @@ -11,10 +11,17 @@ #include "lldb/Initialization/SystemInitializer.h" #include "lldb/Initialization/SystemInitializerCommon.h" +#include "lldb/Utility/FileSpec.h" class SystemInitializerLLGS : public lldb_private::SystemInitializerCommon { public: - SystemInitializerLLGS() : SystemInitializerCommon(nullptr) {} + SystemInitializerLLGS() + : SystemInitializerCommon( + // Finding the shared libraries directory on lldb-server is broken + // since lldb-server isn't dynamically linked with liblldb.so. + // Clearing the filespec here causes GetShlibDir to fail and + // GetSupportExeDir to fall-back to using the binary path instead. + [](lldb_private::FileSpec &file) { file.Clear(); }) {} llvm::Error Initialize() override; void Terminate() override; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits