Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb] Use correct path for debugserver #131609

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

yuvald-sweet-security
Copy link

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.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Mar 17, 2025

@llvm/pr-subscribers-lldb

Author: Yuval Deutscher (yuvald-sweet-security)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/131609.diff

1 Files Affected:

  • (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (+1-1)
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);

@yuvald-sweet-security
Copy link
Author

yuvald-sweet-security commented Mar 17, 2025

Well, looks like the tests really do check a case where lldb and lldb-server are not in the same directory. Should we just try both paths? maybe make GetShlibDir return false if it is linked statically?

EDIT: trying a new approach

@JDevlieghere JDevlieghere requested a review from labath March 19, 2025 18:03
@yuvald-sweet-security
Copy link
Author

Solves #63468

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants