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
|
||||
GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||
GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
|
||||
uint16_t in_port,
|
||||
lldb_private::ProcessLaunchInfo &launch_info,
|
||||
uint16_t &port)
|
||||
uint16_t &out_port)
|
||||
{
|
||||
port = 0;
|
||||
|
||||
out_port = in_port;
|
||||
Error error;
|
||||
// If we locate debugserver, keep that located version around
|
||||
static FileSpec g_debugserver_file_spec;
|
||||
|
@ -651,8 +651,17 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
|||
debugserver_args.AppendArgument(debugserver_path);
|
||||
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
host_and_port[0] = '\0';
|
||||
}
|
||||
|
||||
// use native registers, not the GDB registers
|
||||
debugserver_args.AppendArgument("--native-regs");
|
||||
// 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];
|
||||
|
||||
if (host_and_port)
|
||||
bool listen = false;
|
||||
if (host_and_port[0])
|
||||
{
|
||||
// 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
|
||||
// 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");
|
||||
debugserver_args.AppendArgument(named_pipe_path);
|
||||
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 (::mkfifo(named_pipe_path, 0600) == 0)
|
||||
{
|
||||
debugserver_args.AppendArgument("--named-pipe");
|
||||
debugserver_args.AppendArgument(named_pipe_path);
|
||||
}
|
||||
else
|
||||
named_pipe_path[0] = '\0';
|
||||
}
|
||||
else
|
||||
named_pipe_path[0] = '\0';
|
||||
}
|
||||
else
|
||||
named_pipe_path[0] = '\0';
|
||||
{
|
||||
listen = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -701,10 +721,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
|||
return error;
|
||||
|
||||
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
|
||||
port = connection->GetBoundPort(3);
|
||||
assert (port != 0);
|
||||
out_port = connection->GetBoundPort(3);
|
||||
assert (out_port != 0);
|
||||
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
|
||||
// so that it connects back to the port we are listening to in this process
|
||||
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);
|
||||
assert (error.Success());
|
||||
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();
|
||||
}
|
||||
Host::Unlink(named_pipe_path);
|
||||
}
|
||||
else if (listen)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -121,9 +121,10 @@ public:
|
|||
// supplied connection URL.
|
||||
//------------------------------------------------------------------
|
||||
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,
|
||||
uint16_t &port);
|
||||
uint16_t &out_port);
|
||||
|
||||
void
|
||||
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.
|
||||
ProcessLaunchInfo debugserver_launch_info;
|
||||
StreamString host_and_port;
|
||||
if (hostname.empty())
|
||||
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));
|
||||
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);
|
||||
|
||||
error = StartDebugserverProcess (host_and_port_cstr,
|
||||
error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
|
||||
port,
|
||||
debugserver_launch_info,
|
||||
port);
|
||||
|
||||
|
|
|
@ -167,6 +167,34 @@ namespace {
|
|||
|
||||
} // 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
|
||||
ProcessGDBRemote::GetPluginNameStatic()
|
||||
{
|
||||
|
@ -2514,7 +2542,6 @@ Error
|
|||
ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
|
||||
{
|
||||
Error error;
|
||||
uint16_t port = 0;
|
||||
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
// 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.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,
|
||||
port);
|
||||
|
||||
|
@ -2552,9 +2592,9 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
|||
}
|
||||
else
|
||||
{
|
||||
char connect_url[128];
|
||||
snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
|
||||
error = ConnectToDebugserver (connect_url);
|
||||
StreamString connect_url;
|
||||
connect_url.Printf("connect://%s:%u", hostname, port);
|
||||
error = ConnectToDebugserver (connect_url.GetString().c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue