summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Platform.h23
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp124
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp19
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp1
7 files changed, 139 insertions, 42 deletions
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 103395cee2e..5c878c9b792 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -947,6 +947,29 @@ class ModuleCache;
virtual const std::vector<ConstString> &
GetTrapHandlerSymbolNames ();
+
+ //------------------------------------------------------------------
+ /// Find a support executable that may not live within in the
+ /// standard locations related to LLDB.
+ ///
+ /// Executable might exist within the Platform SDK directories, or
+ /// in standard tool directories within the current IDE that is
+ /// running LLDB.
+ ///
+ /// @param[in] basename
+ /// The basename of the executable to locate in the current
+ /// platform.
+ ///
+ /// @return
+ /// A FileSpec pointing to the executable on disk, or an invalid
+ /// FileSpec if the executable cannot be found.
+ //------------------------------------------------------------------
+ virtual FileSpec
+ LocateExecutable (const char *basename)
+ {
+ return FileSpec();
+ }
+
protected:
bool m_is_host;
// Set to true when we are able to actually set the OS version while
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 26fc4b79d92..b9eb303edde 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1211,11 +1211,13 @@ static const char *const sdk_strings[] = {
static FileSpec
GetXcodeContentsPath ()
{
- const char substr[] = ".app/Contents/";
-
- // First, try based on the current shlib's location
+ static FileSpec g_xcode_filespec;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+
+ const char substr[] = ".app/Contents/";
- {
+ // First, try based on the current shlib's location
FileSpec fspec;
if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec))
@@ -1225,42 +1227,42 @@ GetXcodeContentsPath ()
if (pos != std::string::npos)
{
path_to_shlib.erase(pos + strlen(substr));
- return FileSpec(path_to_shlib.c_str(), false);
+ g_xcode_filespec = FileSpec(path_to_shlib.c_str(), false);
}
}
- }
-
- // Fall back to using xcrun
-
- {
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "xcrun -sdk macosx --show-sdk-path";
- lldb_private::Error error = Host::RunShellCommand (command, // shell command to run
- NULL, // current working directory
- &status, // Put the exit status of the process in here
- &signo, // Put the signal that caused the process to exit in here
- &output, // Get the output from the command and place it in this string
- 3); // Timeout in seconds to wait for shell program to finish
- if (status == 0 && !output.empty())
+
+ // Fall back to using xcrun
+ if (!g_xcode_filespec)
{
- size_t first_non_newline = output.find_last_not_of("\r\n");
- if (first_non_newline != std::string::npos)
- {
- output.erase(first_non_newline+1);
- }
-
- size_t pos = output.rfind(substr);
- if (pos != std::string::npos)
+ int status = 0;
+ int signo = 0;
+ std::string output;
+ const char *command = "xcrun -sdk macosx --show-sdk-path";
+ lldb_private::Error error = Host::RunShellCommand (command, // shell command to run
+ NULL, // current working directory
+ &status, // Put the exit status of the process in here
+ &signo, // Put the signal that caused the process to exit in here
+ &output, // Get the output from the command and place it in this string
+ 3); // Timeout in seconds to wait for shell program to finish
+ if (status == 0 && !output.empty())
{
- output.erase(pos + strlen(substr));
- return FileSpec(output.c_str(), false);
+ size_t first_non_newline = output.find_last_not_of("\r\n");
+ if (first_non_newline != std::string::npos)
+ {
+ output.erase(first_non_newline+1);
+ }
+
+ size_t pos = output.rfind(substr);
+ if (pos != std::string::npos)
+ {
+ output.erase(pos + strlen(substr));
+ g_xcode_filespec = FileSpec(output.c_str(), false);
+ }
}
}
- }
+ });
- return FileSpec();
+ return g_xcode_filespec;
}
bool
@@ -1543,3 +1545,59 @@ PlatformDarwin::GetFullNameForDylib (ConstString basename)
return ConstString(stream.GetData());
}
+
+lldb_private::FileSpec
+PlatformDarwin::LocateExecutable (const char *basename)
+{
+ // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled in with
+ // any executable directories that should be searched.
+ static std::vector<FileSpec> g_executable_dirs;
+
+ // Find the global list of directories that we will search for
+ // executables once so we don't keep doing the work over and over.
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+
+ // When locating executables, trust the DEVELOPER_DIR first if it is set
+ FileSpec xcode_contents_dir;
+ const char *developer_dir_env_var = getenv("DEVELOPER_DIR");
+ if (developer_dir_env_var && developer_dir_env_var[0])
+ {
+ xcode_contents_dir = FileSpec(developer_dir_env_var, true);
+ if (xcode_contents_dir.Exists())
+ xcode_contents_dir.RemoveLastPathComponent();
+ }
+ if (!xcode_contents_dir)
+ {
+ xcode_contents_dir = GetXcodeContentsPath();
+ if (!xcode_contents_dir.Exists())
+ xcode_contents_dir.Clear();
+ }
+ if (xcode_contents_dir)
+ {
+ FileSpec xcode_lldb_resources = xcode_contents_dir;
+ xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
+ xcode_lldb_resources.AppendPathComponent("LLDB.framework");
+ xcode_lldb_resources.AppendPathComponent("Resources");
+ if (xcode_lldb_resources.Exists())
+ {
+ FileSpec dir;
+ dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
+ g_executable_dirs.push_back(dir);
+ }
+ }
+ });
+
+ // Now search the global list of executable directories for the executable we
+ // are looking for
+ for (const auto &executable_dir : g_executable_dirs)
+ {
+ FileSpec executable_file;
+ executable_file.GetDirectory() = executable_dir.GetDirectory();
+ executable_file.GetFilename().SetCString(basename);
+ if (executable_file.Exists())
+ return executable_file;
+ }
+
+ return FileSpec();
+}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index ee604146e7a..4a9e1fc0eec 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -88,6 +88,9 @@ public:
lldb_private::ConstString
GetFullNameForDylib (lldb_private::ConstString basename) override;
+ lldb_private::FileSpec
+ LocateExecutable (const char *basename) override;
+
protected:
void
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index e5ea80f2fae..0bbee854dc4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -30,6 +30,7 @@
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "llvm/ADT/SmallString.h"
@@ -1113,6 +1114,7 @@ GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
Error
GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
uint16_t in_port,
+ Platform *platform,
ProcessLaunchInfo &launch_info,
uint16_t &out_port)
{
@@ -1157,11 +1159,20 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
}
else
{
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
-
+ debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
+ if (debugserver_file_spec)
+ {
+ // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
+ debugserver_exists = true;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
+ }
+ // Don't cache the platform specific GDB server binary as it could change
+ // from platform to platform
g_debugserver_file_spec.Clear();
- debugserver_file_spec.Clear();
}
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 7379bb3aa09..94ffa512884 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -169,6 +169,7 @@ public:
Error
StartDebugserverProcess (const char *hostname,
uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
+ Platform *platform, // If non NULL, then check with the platform for the GDB server binary if it can't be located
ProcessLaunchInfo &launch_info,
uint16_t &out_port);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 742dee57ca5..592d7f7f27c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -138,11 +138,11 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
- Error error = StartDebugserverProcess (
- platform_ip.c_str(),
- port,
- debugserver_launch_info,
- port);
+ Error error = StartDebugserverProcess (platform_ip.c_str(),
+ port,
+ nullptr,
+ debugserver_launch_info,
+ port);
lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 84dc10a5afc..5b6f9794f5a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3568,6 +3568,7 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
error = m_gdb_comm.StartDebugserverProcess (hostname,
port,
+ GetTarget().GetPlatform().get(),
debugserver_launch_info,
port);
OpenPOWER on IntegriCloud