https://github.com/yuvald-sweet-security created https://github.com/llvm/llvm-project/pull/131609
Hello, 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`. In such a scenario, running `lldb-server-19 platform --server --listen '*:1338' --log-channels "lldb all"` works as intended, but running the absolute path of the symlink (`/usr/bin/lldb-server-19 platform --server --listen '*:1338' --log-channels "lldb all"`) fails with: ``` shlib dir -> `/usr/bin/` Attempting to derive the path /bin relative to liblldb install path: /usr/bin Derived the path as: /usr/bin support exe dir -> `/usr/bin/` GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer() debugserver launch failed: unable to locate lldb-server-19.1.7 ``` 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). Given the above information, the most logical solution seems to be just ditching `GetSupportExeDir` in favor of `GetProgramFileSpec`, but I'm not sure what are the potential implications of this on different packaging of LLDB - perhaps there are situations where the `lldb` binary is not located in the same directory with `lldb-server`, and so we still want to use the follow-the-path-to-liblldb logic there? Please advise on how to proceed with this. >From f47298e0f29a2a73d656ba5270557ca139688499 Mon Sep 17 00:00:00 2001 From: Yuval Deutscher <yuvald@sweet.security> Date: Mon, 17 Mar 2025 14:37:26 +0200 Subject: [PATCH] [lldb] Use correct path for debugserver --- .../Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index dad72a176b5fa..e754d01be3629 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -906,7 +906,7 @@ FileSpec GDBRemoteCommunication::GetDebugserverPath(Platform *platform) { FileSystem::Instance().Exists(debugserver_file_spec); if (!debugserver_exists) { // The debugserver binary is in the LLDB.framework/Resources directory. - debugserver_file_spec = HostInfo::GetSupportExeDir(); + debugserver_file_spec.SetDirectory(HostInfo::GetProgramFileSpec().GetDirectory()); if (debugserver_file_spec) { debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME); debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits