diff options
author | Greg Clayton <gclayton@apple.com> | 2014-01-10 22:24:11 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2014-01-10 22:24:11 +0000 |
commit | fda4fab5059aa88e711315a61fccf78b23cc64ce (patch) | |
tree | 2eeac5edbf27bf28cf8d953358ebddb733667c97 | |
parent | 9485dcfb1a7500fa0e15c71c4c27919c9e2924a7 (diff) | |
download | bcm5719-llvm-fda4fab5059aa88e711315a61fccf78b23cc64ce.tar.gz bcm5719-llvm-fda4fab5059aa88e711315a61fccf78b23cc64ce.zip |
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
4 files changed, 100 insertions, 37 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 76817f5930d..b3ea8b481df 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -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,11 +766,15 @@ 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 { // Make sure we actually connect with the debugserver... diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index a4121c7219e..066b5bce242 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -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); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 9983626bb24..91658b98d61 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -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); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 877205abd3a..20b14951778 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -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()); } } |