aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2025-06-27 11:16:57 +0200
committerGitHub <noreply@github.com>2025-06-27 11:16:57 +0200
commit2c90c0b90cbdfbd069b2e79d6a2c3e3b160bf896 (patch)
tree78ef76376e2dc2c23607e883aa57dd8b540a599f /lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
parent7255c3aee3ebd94d51067d4682400444a97a8faa (diff)
downloadllvm-2c90c0b90cbdfbd069b2e79d6a2c3e3b160bf896.zip
llvm-2c90c0b90cbdfbd069b2e79d6a2c3e3b160bf896.tar.gz
llvm-2c90c0b90cbdfbd069b2e79d6a2c3e3b160bf896.tar.bz2
[lldb] Extract debug server location code (#145706)
.. from the guts of GDBRemoteCommunication to ~top level. This is motivated by #131519 and by the fact that's impossible to guess whether the author of a symlink intended it to be a "convenience shortcut" -- meaning it should be resolved before looking for related files; or an "implementation detail" -- meaning the related files should be located near the symlink itself. This debate is particularly ridiculous when it comes to lldb-server running in platform mode, because it also functions as a debug server, so what we really just need to do is to pass /proc/self/exe in a platform-independent manner. Moving the location logic higher up achieves that as lldb-platform (on non-macos) can pass `HostInfo::GetProgramFileSpec`, while liblldb can use the existing complex logic (which only worked on liblldb anyway as lldb-platform doesn't have a lldb_private::Platform instance). Another benefit of this patch is a reduction in dependency from GDBRemoteCommunication to the rest of liblldb (achieved by avoiding the Platform dependency).
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
1 files changed, 58 insertions, 4 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3f9c4dd..a2c34dd 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -34,6 +34,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/PseudoTerminal.h"
@@ -92,7 +93,14 @@
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
+#if defined(__APPLE__)
#define DEBUGSERVER_BASENAME "debugserver"
+#elif defined(_WIN32)
+#define DEBUGSERVER_BASENAME "lldb-server.exe"
+#else
+#define DEBUGSERVER_BASENAME "lldb-server"
+#endif
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
@@ -3448,6 +3456,51 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
return error;
}
+static FileSpec GetDebugserverPath(Platform &platform) {
+ Log *log = GetLog(GDBRLog::Process);
+ // If we locate debugserver, keep that located version around
+ static FileSpec g_debugserver_file_spec;
+ FileSpec debugserver_file_spec;
+
+ Environment host_env = Host::GetEnvironment();
+
+ // Always check to see if we have an environment override for the path to the
+ // debugserver to use and use it if we do.
+ std::string env_debugserver_path = host_env.lookup("LLDB_DEBUGSERVER_PATH");
+ if (!env_debugserver_path.empty()) {
+ debugserver_file_spec.SetFile(env_debugserver_path,
+ FileSpec::Style::native);
+ LLDB_LOG(log, "gdb-remote stub exe path set from environment variable: {0}",
+ env_debugserver_path);
+ } else
+ debugserver_file_spec = g_debugserver_file_spec;
+ if (FileSystem::Instance().Exists(debugserver_file_spec))
+ return debugserver_file_spec;
+
+ // The debugserver binary is in the LLDB.framework/Resources directory.
+ debugserver_file_spec = HostInfo::GetSupportExeDir();
+ if (debugserver_file_spec) {
+ debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
+ if (FileSystem::Instance().Exists(debugserver_file_spec)) {
+ LLDB_LOG(log, "found gdb-remote stub exe '{0}'", debugserver_file_spec);
+
+ g_debugserver_file_spec = debugserver_file_spec;
+ } else {
+ debugserver_file_spec = platform.LocateExecutable(DEBUGSERVER_BASENAME);
+ if (!debugserver_file_spec) {
+ // Platform::LocateExecutable() wouldn't return a path if it doesn't
+ // exist
+ LLDB_LOG(log, "could not find gdb-remote stub exe '{0}'",
+ debugserver_file_spec);
+ }
+ // Don't cache the platform specific GDB server binary as it could
+ // change from platform to platform
+ g_debugserver_file_spec.Clear();
+ }
+ }
+ return debugserver_file_spec;
+}
+
Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
const ProcessInfo &process_info) {
using namespace std::placeholders; // For _1, _2, etc.
@@ -3466,6 +3519,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3));
debugserver_launch_info.SetUserID(process_info.GetUserID());
+ FileSpec debugserver_path = GetDebugserverPath(*GetTarget().GetPlatform());
+
#if defined(__APPLE__)
// On macOS 11, we need to support x86_64 applications translated to
// arm64. We check whether a binary is translated and spawn the correct
@@ -3478,12 +3533,12 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
NULL, 0) == 0 &&
bufsize > 0) {
if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
- FileSpec rosetta_debugserver(
- "/Library/Apple/usr/libexec/oah/debugserver");
- debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false);
+ debugserver_path = FileSpec("/Library/Apple/usr/libexec/oah/debugserver");
}
}
#endif
+ debugserver_launch_info.SetExecutableFile(debugserver_path,
+ /*add_exe_file_as_first_arg=*/true);
llvm::Expected<Socket::Pair> socket_pair = Socket::CreatePair();
if (!socket_pair)
@@ -3495,7 +3550,6 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
return error;
error = m_gdb_comm.StartDebugserverProcess(shared_socket.GetSendableFD(),
- GetTarget().GetPlatform().get(),
debugserver_launch_info, nullptr);
if (error.Fail()) {