forked from OSchip/llvm-project
Allow LLDB.framework to locate debugserver even when it doesn't exist in the LLDB.framework.
This allows open source MacOSX clients to not have to build debugserver and the current LLDB can find debugserver inside the selected Xcode.app on your system. <rdar://problem/23167253> llvm-svn: 250735
This commit is contained in:
parent
238de51eed
commit
6988abc14d
|
@ -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
|
||||
|
|
|
@ -1211,11 +1211,13 @@ static const char *const sdk_strings[] = {
|
|||
static FileSpec
|
||||
GetXcodeContentsPath ()
|
||||
{
|
||||
const char substr[] = ".app/Contents/";
|
||||
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
|
||||
|
||||
{
|
||||
// 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)
|
||||
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(first_non_newline+1);
|
||||
}
|
||||
|
||||
size_t pos = output.rfind(substr);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ public:
|
|||
lldb_private::ConstString
|
||||
GetFullNameForDylib (lldb_private::ConstString basename) override;
|
||||
|
||||
lldb_private::FileSpec
|
||||
LocateExecutable (const char *basename) override;
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -3568,6 +3568,7 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
|||
|
||||
error = m_gdb_comm.StartDebugserverProcess (hostname,
|
||||
port,
|
||||
GetTarget().GetPlatform().get(),
|
||||
debugserver_launch_info,
|
||||
port);
|
||||
|
||||
|
|
Loading…
Reference in New Issue