forked from OSchip/llvm-project
Revert to getting a random port and sending that down to debugserver for iOS. The sandboxing is not letting debugserver reverse connect back to lldb.
<rdar://problem/15789865> llvm-svn: 198963
This commit is contained in:
parent
9485dcfb1a
commit
fda4fab505
|
@ -598,12 +598,12 @@ GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
Error
|
Error
|
||||||
GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
|
||||||
|
uint16_t in_port,
|
||||||
lldb_private::ProcessLaunchInfo &launch_info,
|
lldb_private::ProcessLaunchInfo &launch_info,
|
||||||
uint16_t &port)
|
uint16_t &out_port)
|
||||||
{
|
{
|
||||||
port = 0;
|
out_port = in_port;
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
// If we locate debugserver, keep that located version around
|
// If we locate debugserver, keep that located version around
|
||||||
static FileSpec g_debugserver_file_spec;
|
static FileSpec g_debugserver_file_spec;
|
||||||
|
@ -651,8 +651,17 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||||
debugserver_args.AppendArgument(debugserver_path);
|
debugserver_args.AppendArgument(debugserver_path);
|
||||||
|
|
||||||
// If a host and port is supplied then use it
|
// If a host and port is supplied then use it
|
||||||
if (host_and_port)
|
char host_and_port[128];
|
||||||
|
if (hostname)
|
||||||
|
{
|
||||||
|
snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
|
||||||
debugserver_args.AppendArgument(host_and_port);
|
debugserver_args.AppendArgument(host_and_port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
host_and_port[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// use native registers, not the GDB registers
|
// use native registers, not the GDB registers
|
||||||
debugserver_args.AppendArgument("--native-regs");
|
debugserver_args.AppendArgument("--native-regs");
|
||||||
// make debugserver run in its own session so signals generated by
|
// make debugserver run in its own session so signals generated by
|
||||||
|
@ -661,34 +670,45 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||||
|
|
||||||
char named_pipe_path[PATH_MAX];
|
char named_pipe_path[PATH_MAX];
|
||||||
|
|
||||||
if (host_and_port)
|
bool listen = false;
|
||||||
|
if (host_and_port[0])
|
||||||
{
|
{
|
||||||
// Create a temporary file to get the stdout/stderr and redirect the
|
// Create a temporary file to get the stdout/stderr and redirect the
|
||||||
// output of the command into this file. We will later read this file
|
// output of the command into this file. We will later read this file
|
||||||
// if all goes well and fill the data into "command_output_ptr"
|
// if all goes well and fill the data into "command_output_ptr"
|
||||||
FileSpec tmpdir_file_spec;
|
|
||||||
if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
|
|
||||||
{
|
|
||||||
tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
|
|
||||||
strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::mktemp (named_pipe_path))
|
if (in_port == 0)
|
||||||
{
|
{
|
||||||
if (::mkfifo(named_pipe_path, 0600) == 0)
|
// Binding to port zero, we need to figure out what port it ends up
|
||||||
|
// using using a named pipe...
|
||||||
|
FileSpec tmpdir_file_spec;
|
||||||
|
if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
|
||||||
{
|
{
|
||||||
debugserver_args.AppendArgument("--named-pipe");
|
tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
|
||||||
debugserver_args.AppendArgument(named_pipe_path);
|
strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::mktemp (named_pipe_path))
|
||||||
|
{
|
||||||
|
if (::mkfifo(named_pipe_path, 0600) == 0)
|
||||||
|
{
|
||||||
|
debugserver_args.AppendArgument("--named-pipe");
|
||||||
|
debugserver_args.AppendArgument(named_pipe_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
named_pipe_path[0] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
named_pipe_path[0] = '\0';
|
named_pipe_path[0] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
named_pipe_path[0] = '\0';
|
{
|
||||||
|
listen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -701,10 +721,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
|
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
|
||||||
port = connection->GetBoundPort(3);
|
out_port = connection->GetBoundPort(3);
|
||||||
assert (port != 0);
|
assert (out_port != 0);
|
||||||
char port_cstr[32];
|
char port_cstr[32];
|
||||||
snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", port);
|
snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", out_port);
|
||||||
// Send the host and port down that debugserver and specify an option
|
// Send the host and port down that debugserver and specify an option
|
||||||
// so that it connects back to the port we are listening to in this process
|
// so that it connects back to the port we are listening to in this process
|
||||||
debugserver_args.AppendArgument("--reverse-connect");
|
debugserver_args.AppendArgument("--reverse-connect");
|
||||||
|
@ -746,10 +766,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||||
error = name_pipe_file.Read(port_cstr, num_bytes);
|
error = name_pipe_file.Read(port_cstr, num_bytes);
|
||||||
assert (error.Success());
|
assert (error.Success());
|
||||||
assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
|
assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
|
||||||
port = Args::StringToUInt32(port_cstr, 0);
|
out_port = Args::StringToUInt32(port_cstr, 0);
|
||||||
name_pipe_file.Close();
|
name_pipe_file.Close();
|
||||||
}
|
}
|
||||||
Host::Unlink(named_pipe_path);
|
Host::Unlink(named_pipe_path);
|
||||||
|
}
|
||||||
|
else if (listen)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,9 +121,10 @@ public:
|
||||||
// supplied connection URL.
|
// supplied connection URL.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
lldb_private::Error
|
lldb_private::Error
|
||||||
StartDebugserverProcess (const char *host_and_port,
|
StartDebugserverProcess (const char *hostname,
|
||||||
|
uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
|
||||||
lldb_private::ProcessLaunchInfo &launch_info,
|
lldb_private::ProcessLaunchInfo &launch_info,
|
||||||
uint16_t &port);
|
uint16_t &out_port);
|
||||||
|
|
||||||
void
|
void
|
||||||
DumpHistory(lldb_private::Stream &strm);
|
DumpHistory(lldb_private::Stream &strm);
|
||||||
|
|
|
@ -841,18 +841,16 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
|
||||||
{
|
{
|
||||||
// Spawn a debugserver and try to get the port it listens to.
|
// Spawn a debugserver and try to get the port it listens to.
|
||||||
ProcessLaunchInfo debugserver_launch_info;
|
ProcessLaunchInfo debugserver_launch_info;
|
||||||
StreamString host_and_port;
|
|
||||||
if (hostname.empty())
|
if (hostname.empty())
|
||||||
hostname = "localhost";
|
hostname = "localhost";
|
||||||
host_and_port.Printf("%s:%u", hostname.c_str(), port);
|
|
||||||
const char *host_and_port_cstr = host_and_port.GetString().c_str();
|
|
||||||
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr);
|
log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
|
||||||
|
|
||||||
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
||||||
|
|
||||||
error = StartDebugserverProcess (host_and_port_cstr,
|
error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
|
||||||
|
port,
|
||||||
debugserver_launch_info,
|
debugserver_launch_info,
|
||||||
port);
|
port);
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,34 @@ namespace {
|
||||||
|
|
||||||
} // anonymous namespace end
|
} // anonymous namespace end
|
||||||
|
|
||||||
|
static bool rand_initialized = false;
|
||||||
|
|
||||||
|
// TODO Randomly assigning a port is unsafe. We should get an unused
|
||||||
|
// ephemeral port from the kernel and make sure we reserve it before passing
|
||||||
|
// it to debugserver.
|
||||||
|
|
||||||
|
#if defined (__APPLE__)
|
||||||
|
#define LOW_PORT (IPPORT_RESERVED)
|
||||||
|
#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
|
||||||
|
#else
|
||||||
|
#define LOW_PORT (1024u)
|
||||||
|
#define HIGH_PORT (49151u)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
get_random_port ()
|
||||||
|
{
|
||||||
|
if (!rand_initialized)
|
||||||
|
{
|
||||||
|
time_t seed = time(NULL);
|
||||||
|
|
||||||
|
rand_initialized = true;
|
||||||
|
srand(seed);
|
||||||
|
}
|
||||||
|
return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lldb_private::ConstString
|
lldb_private::ConstString
|
||||||
ProcessGDBRemote::GetPluginNameStatic()
|
ProcessGDBRemote::GetPluginNameStatic()
|
||||||
{
|
{
|
||||||
|
@ -2514,7 +2542,6 @@ Error
|
||||||
ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
|
ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
uint16_t port = 0;
|
|
||||||
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
|
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
|
||||||
{
|
{
|
||||||
// If we locate debugserver, keep that located version around
|
// If we locate debugserver, keep that located version around
|
||||||
|
@ -2524,7 +2551,20 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
||||||
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
|
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
|
||||||
debugserver_launch_info.SetUserID(process_info.GetUserID());
|
debugserver_launch_info.SetUserID(process_info.GetUserID());
|
||||||
|
|
||||||
error = m_gdb_comm.StartDebugserverProcess (NULL,
|
#if defined (__APPLE__) && defined (__arm__)
|
||||||
|
// On iOS, still do a local connection using a random port
|
||||||
|
const char *hostname = "localhost";
|
||||||
|
uint16_t port = get_random_port ();
|
||||||
|
#else
|
||||||
|
// Set hostname being NULL to do the reverse connect where debugserver
|
||||||
|
// will bind to port zero and it will communicate back to us the port
|
||||||
|
// that we will connect to
|
||||||
|
const char *hostname = NULL;
|
||||||
|
uint16_t port = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
error = m_gdb_comm.StartDebugserverProcess (hostname,
|
||||||
|
port,
|
||||||
debugserver_launch_info,
|
debugserver_launch_info,
|
||||||
port);
|
port);
|
||||||
|
|
||||||
|
@ -2552,9 +2592,9 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char connect_url[128];
|
StreamString connect_url;
|
||||||
snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
|
connect_url.Printf("connect://%s:%u", hostname, port);
|
||||||
error = ConnectToDebugserver (connect_url);
|
error = ConnectToDebugserver (connect_url.GetString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue