xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (revision c00cf4a0688ea62229a5d44d5f000bc62c172263)
1 //===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 #include "GDBRemoteCommunication.h"
12 
13 // C Includes
14 #include <limits.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 
18 // C++ Includes
19 // Other libraries and framework includes
20 #include "lldb/Core/ConnectionFileDescriptor.h"
21 #include "lldb/Core/Log.h"
22 #include "lldb/Core/StreamFile.h"
23 #include "lldb/Core/StreamString.h"
24 #include "lldb/Host/FileSpec.h"
25 #include "lldb/Host/FileSystem.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Host/Socket.h"
28 #include "lldb/Host/TimeValue.h"
29 #include "lldb/Target/Process.h"
30 
31 // Project includes
32 #include "ProcessGDBRemoteLog.h"
33 
34 #if defined(__APPLE__)
35 # define DEBUGSERVER_BASENAME    "debugserver"
36 #else
37 # define DEBUGSERVER_BASENAME    "lldb-gdbserver"
38 #endif
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 GDBRemoteCommunication::History::History (uint32_t size) :
44     m_packets(),
45     m_curr_idx (0),
46     m_total_packet_count (0),
47     m_dumped_to_log (false)
48 {
49     m_packets.resize(size);
50 }
51 
52 GDBRemoteCommunication::History::~History ()
53 {
54 }
55 
56 void
57 GDBRemoteCommunication::History::AddPacket (char packet_char,
58                                             PacketType type,
59                                             uint32_t bytes_transmitted)
60 {
61     const size_t size = m_packets.size();
62     if (size > 0)
63     {
64         const uint32_t idx = GetNextIndex();
65         m_packets[idx].packet.assign (1, packet_char);
66         m_packets[idx].type = type;
67         m_packets[idx].bytes_transmitted = bytes_transmitted;
68         m_packets[idx].packet_idx = m_total_packet_count;
69         m_packets[idx].tid = Host::GetCurrentThreadID();
70     }
71 }
72 
73 void
74 GDBRemoteCommunication::History::AddPacket (const std::string &src,
75                                             uint32_t src_len,
76                                             PacketType type,
77                                             uint32_t bytes_transmitted)
78 {
79     const size_t size = m_packets.size();
80     if (size > 0)
81     {
82         const uint32_t idx = GetNextIndex();
83         m_packets[idx].packet.assign (src, 0, src_len);
84         m_packets[idx].type = type;
85         m_packets[idx].bytes_transmitted = bytes_transmitted;
86         m_packets[idx].packet_idx = m_total_packet_count;
87         m_packets[idx].tid = Host::GetCurrentThreadID();
88     }
89 }
90 
91 void
92 GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const
93 {
94     const uint32_t size = GetNumPacketsInHistory ();
95     const uint32_t first_idx = GetFirstSavedPacketIndex ();
96     const uint32_t stop_idx = m_curr_idx + size;
97     for (uint32_t i = first_idx;  i < stop_idx; ++i)
98     {
99         const uint32_t idx = NormalizeIndex (i);
100         const Entry &entry = m_packets[idx];
101         if (entry.type == ePacketTypeInvalid || entry.packet.empty())
102             break;
103         strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
104                      entry.packet_idx,
105                      entry.tid,
106                      entry.bytes_transmitted,
107                      (entry.type == ePacketTypeSend) ? "send" : "read",
108                      entry.packet.c_str());
109     }
110 }
111 
112 void
113 GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const
114 {
115     if (log && !m_dumped_to_log)
116     {
117         m_dumped_to_log = true;
118         const uint32_t size = GetNumPacketsInHistory ();
119         const uint32_t first_idx = GetFirstSavedPacketIndex ();
120         const uint32_t stop_idx = m_curr_idx + size;
121         for (uint32_t i = first_idx;  i < stop_idx; ++i)
122         {
123             const uint32_t idx = NormalizeIndex (i);
124             const Entry &entry = m_packets[idx];
125             if (entry.type == ePacketTypeInvalid || entry.packet.empty())
126                 break;
127             log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
128                          entry.packet_idx,
129                          entry.tid,
130                          entry.bytes_transmitted,
131                          (entry.type == ePacketTypeSend) ? "send" : "read",
132                          entry.packet.c_str());
133         }
134     }
135 }
136 
137 //----------------------------------------------------------------------
138 // GDBRemoteCommunication constructor
139 //----------------------------------------------------------------------
140 GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
141                                                const char *listener_name,
142                                                bool is_platform) :
143     Communication(comm_name),
144 #ifdef LLDB_CONFIGURATION_DEBUG
145     m_packet_timeout (1000),
146 #else
147     m_packet_timeout (1),
148 #endif
149     m_sequence_mutex (Mutex::eMutexTypeRecursive),
150     m_public_is_running (false),
151     m_private_is_running (false),
152     m_history (512),
153     m_send_acks (true),
154     m_is_platform (is_platform),
155     m_listen_thread (LLDB_INVALID_HOST_THREAD),
156     m_listen_url ()
157 {
158 }
159 
160 //----------------------------------------------------------------------
161 // Destructor
162 //----------------------------------------------------------------------
163 GDBRemoteCommunication::~GDBRemoteCommunication()
164 {
165     if (IsConnected())
166     {
167         Disconnect();
168     }
169 }
170 
171 char
172 GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
173 {
174     int checksum = 0;
175 
176     for (size_t i = 0; i < payload_length; ++i)
177         checksum += payload[i];
178 
179     return checksum & 255;
180 }
181 
182 size_t
183 GDBRemoteCommunication::SendAck ()
184 {
185     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
186     ConnectionStatus status = eConnectionStatusSuccess;
187     char ch = '+';
188     const size_t bytes_written = Write (&ch, 1, status, NULL);
189     if (log)
190         log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
191     m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
192     return bytes_written;
193 }
194 
195 size_t
196 GDBRemoteCommunication::SendNack ()
197 {
198     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
199     ConnectionStatus status = eConnectionStatusSuccess;
200     char ch = '-';
201     const size_t bytes_written = Write (&ch, 1, status, NULL);
202     if (log)
203         log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
204     m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
205     return bytes_written;
206 }
207 
208 GDBRemoteCommunication::PacketResult
209 GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
210 {
211     Mutex::Locker locker(m_sequence_mutex);
212     return SendPacketNoLock (payload, payload_length);
213 }
214 
215 GDBRemoteCommunication::PacketResult
216 GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
217 {
218     if (IsConnected())
219     {
220         StreamString packet(0, 4, eByteOrderBig);
221 
222         packet.PutChar('$');
223         packet.Write (payload, payload_length);
224         packet.PutChar('#');
225         packet.PutHex8(CalculcateChecksum (payload, payload_length));
226 
227         Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
228         ConnectionStatus status = eConnectionStatusSuccess;
229         size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
230         if (log)
231         {
232             // If logging was just enabled and we have history, then dump out what
233             // we have to the log so we get the historical context. The Dump() call that
234             // logs all of the packet will set a boolean so that we don't dump this more
235             // than once
236             if (!m_history.DidDumpToLog ())
237                 m_history.Dump (log);
238 
239             log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData());
240         }
241 
242         m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written);
243 
244 
245         if (bytes_written == packet.GetSize())
246         {
247             if (GetSendAcks ())
248                 return GetAck ();
249             else
250                 return PacketResult::Success;
251         }
252         else
253         {
254             if (log)
255                 log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
256         }
257     }
258     return PacketResult::ErrorSendFailed;
259 }
260 
261 GDBRemoteCommunication::PacketResult
262 GDBRemoteCommunication::GetAck ()
263 {
264     StringExtractorGDBRemote packet;
265     PacketResult result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ());
266     if (result == PacketResult::Success)
267     {
268         if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
269             return PacketResult::Success;
270         else
271             return PacketResult::ErrorSendAck;
272     }
273     return result;
274 }
275 
276 bool
277 GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
278 {
279     if (IsRunning())
280         return locker.TryLock (m_sequence_mutex, failure_message);
281 
282     locker.Lock (m_sequence_mutex);
283     return true;
284 }
285 
286 
287 bool
288 GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
289 {
290     return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
291 }
292 
293 GDBRemoteCommunication::PacketResult
294 GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec)
295 {
296     uint8_t buffer[8192];
297     Error error;
298 
299     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
300 
301     // Check for a packet from our cache first without trying any reading...
302     if (CheckForPacket (NULL, 0, packet))
303         return PacketResult::Success;
304 
305     bool timed_out = false;
306     bool disconnected = false;
307     while (IsConnected() && !timed_out)
308     {
309         lldb::ConnectionStatus status = eConnectionStatusNoConnection;
310         size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
311 
312         if (log)
313             log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
314                          __PRETTY_FUNCTION__,
315                          timeout_usec,
316                          Communication::ConnectionStatusAsCString (status),
317                          error.AsCString(),
318                          (uint64_t)bytes_read);
319 
320         if (bytes_read > 0)
321         {
322             if (CheckForPacket (buffer, bytes_read, packet))
323                 return PacketResult::Success;
324         }
325         else
326         {
327             switch (status)
328             {
329             case eConnectionStatusTimedOut:
330             case eConnectionStatusInterrupted:
331                 timed_out = true;
332                 break;
333             case eConnectionStatusSuccess:
334                 //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
335                 break;
336 
337             case eConnectionStatusEndOfFile:
338             case eConnectionStatusNoConnection:
339             case eConnectionStatusLostConnection:
340             case eConnectionStatusError:
341                 disconnected = true;
342                 Disconnect();
343                 break;
344             }
345         }
346     }
347     packet.Clear ();
348     if (disconnected)
349         return PacketResult::ErrorDisconnected;
350     if (timed_out)
351         return PacketResult::ErrorReplyTimeout;
352     else
353         return PacketResult::ErrorReplyFailed;
354 }
355 
356 bool
357 GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
358 {
359     // Put the packet data into the buffer in a thread safe fashion
360     Mutex::Locker locker(m_bytes_mutex);
361 
362     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
363 
364     if (src && src_len > 0)
365     {
366         if (log && log->GetVerbose())
367         {
368             StreamString s;
369             log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
370                          __FUNCTION__,
371                          (uint32_t)src_len,
372                          (uint32_t)src_len,
373                          src);
374         }
375         m_bytes.append ((const char *)src, src_len);
376     }
377 
378     // Parse up the packets into gdb remote packets
379     if (!m_bytes.empty())
380     {
381         // end_idx must be one past the last valid packet byte. Start
382         // it off with an invalid value that is the same as the current
383         // index.
384         size_t content_start = 0;
385         size_t content_length = 0;
386         size_t total_length = 0;
387         size_t checksum_idx = std::string::npos;
388 
389         switch (m_bytes[0])
390         {
391             case '+':       // Look for ack
392             case '-':       // Look for cancel
393             case '\x03':    // ^C to halt target
394                 content_length = total_length = 1;  // The command is one byte long...
395                 break;
396 
397             case '$':
398                 // Look for a standard gdb packet?
399                 {
400                     size_t hash_pos = m_bytes.find('#');
401                     if (hash_pos != std::string::npos)
402                     {
403                         if (hash_pos + 2 < m_bytes.size())
404                         {
405                             checksum_idx = hash_pos + 1;
406                             // Skip the dollar sign
407                             content_start = 1;
408                             // Don't include the # in the content or the $ in the content length
409                             content_length = hash_pos - 1;
410 
411                             total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
412                         }
413                         else
414                         {
415                             // Checksum bytes aren't all here yet
416                             content_length = std::string::npos;
417                         }
418                     }
419                 }
420                 break;
421 
422             default:
423                 {
424                     // We have an unexpected byte and we need to flush all bad
425                     // data that is in m_bytes, so we need to find the first
426                     // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
427                     // or '$' character (start of packet header) or of course,
428                     // the end of the data in m_bytes...
429                     const size_t bytes_len = m_bytes.size();
430                     bool done = false;
431                     uint32_t idx;
432                     for (idx = 1; !done && idx < bytes_len; ++idx)
433                     {
434                         switch (m_bytes[idx])
435                         {
436                         case '+':
437                         case '-':
438                         case '\x03':
439                         case '$':
440                             done = true;
441                             break;
442 
443                         default:
444                             break;
445                         }
446                     }
447                     if (log)
448                         log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
449                                      __FUNCTION__, idx, idx, m_bytes.c_str());
450                     m_bytes.erase(0, idx);
451                 }
452                 break;
453         }
454 
455         if (content_length == std::string::npos)
456         {
457             packet.Clear();
458             return false;
459         }
460         else if (total_length > 0)
461         {
462 
463             // We have a valid packet...
464             assert (content_length <= m_bytes.size());
465             assert (total_length <= m_bytes.size());
466             assert (content_length <= total_length);
467             const size_t content_end = content_start + content_length;
468 
469             bool success = true;
470             std::string &packet_str = packet.GetStringRef();
471 
472 
473             if (log)
474             {
475                 // If logging was just enabled and we have history, then dump out what
476                 // we have to the log so we get the historical context. The Dump() call that
477                 // logs all of the packet will set a boolean so that we don't dump this more
478                 // than once
479                 if (!m_history.DidDumpToLog ())
480                     m_history.Dump (log);
481 
482                 bool binary = false;
483                 // Only detect binary for packets that start with a '$' and have a '#CC' checksum
484                 if (m_bytes[0] == '$' && total_length > 4)
485                 {
486                     for (size_t i=0; !binary && i<total_length; ++i)
487                     {
488                         if (isprint(m_bytes[i]) == 0)
489                             binary = true;
490                     }
491                 }
492                 if (binary)
493                 {
494                     StreamString strm;
495                     // Packet header...
496                     strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
497                     for (size_t i=content_start; i<content_end; ++i)
498                     {
499                         // Remove binary escaped bytes when displaying the packet...
500                         const char ch = m_bytes[i];
501                         if (ch == 0x7d)
502                         {
503                             // 0x7d is the escape character.  The next character is to
504                             // be XOR'd with 0x20.
505                             const char escapee = m_bytes[++i] ^ 0x20;
506                             strm.Printf("%2.2x", escapee);
507                         }
508                         else
509                         {
510                             strm.Printf("%2.2x", (uint8_t)ch);
511                         }
512                     }
513                     // Packet footer...
514                     strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
515                     log->PutCString(strm.GetString().c_str());
516                 }
517                 else
518                 {
519                     log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
520                 }
521             }
522 
523             m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
524 
525             // Clear packet_str in case there is some existing data in it.
526             packet_str.clear();
527             // Copy the packet from m_bytes to packet_str expanding the
528             // run-length encoding in the process.
529             // Reserve enough byte for the most common case (no RLE used)
530             packet_str.reserve(m_bytes.length());
531             for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
532             {
533                 if (*c == '*')
534                 {
535                     // '*' indicates RLE. Next character will give us the
536                     // repeat count and previous character is what is to be
537                     // repeated.
538                     char char_to_repeat = packet_str.back();
539                     // Number of time the previous character is repeated
540                     int repeat_count = *++c + 3 - ' ';
541                     // We have the char_to_repeat and repeat_count. Now push
542                     // it in the packet.
543                     for (int i = 0; i < repeat_count; ++i)
544                         packet_str.push_back(char_to_repeat);
545                 }
546                 else if (*c == 0x7d)
547                 {
548                     // 0x7d is the escape character.  The next character is to
549                     // be XOR'd with 0x20.
550                     char escapee = *++c ^ 0x20;
551                     packet_str.push_back(escapee);
552                 }
553                 else
554                 {
555                     packet_str.push_back(*c);
556                 }
557             }
558 
559             if (m_bytes[0] == '$')
560             {
561                 assert (checksum_idx < m_bytes.size());
562                 if (::isxdigit (m_bytes[checksum_idx+0]) ||
563                     ::isxdigit (m_bytes[checksum_idx+1]))
564                 {
565                     if (GetSendAcks ())
566                     {
567                         const char *packet_checksum_cstr = &m_bytes[checksum_idx];
568                         char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
569                         char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
570                         success = packet_checksum == actual_checksum;
571                         if (!success)
572                         {
573                             if (log)
574                                 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
575                                              (int)(total_length),
576                                              m_bytes.c_str(),
577                                              (uint8_t)packet_checksum,
578                                              (uint8_t)actual_checksum);
579                         }
580                         // Send the ack or nack if needed
581                         if (!success)
582                             SendNack();
583                         else
584                             SendAck();
585                     }
586                 }
587                 else
588                 {
589                     success = false;
590                     if (log)
591                         log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
592                 }
593             }
594 
595             m_bytes.erase(0, total_length);
596             packet.SetFilePos(0);
597             return success;
598         }
599     }
600     packet.Clear();
601     return false;
602 }
603 
604 Error
605 GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
606 {
607     Error error;
608     if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
609     {
610         error.SetErrorString("listen thread already running");
611     }
612     else
613     {
614         char listen_url[512];
615         if (hostname && hostname[0])
616             snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
617         else
618             snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
619         m_listen_url = listen_url;
620         SetConnection(new ConnectionFileDescriptor());
621         m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error);
622     }
623     return error;
624 }
625 
626 bool
627 GDBRemoteCommunication::JoinListenThread ()
628 {
629     if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
630     {
631         Host::ThreadJoin(m_listen_thread, NULL, NULL);
632         m_listen_thread = LLDB_INVALID_HOST_THREAD;
633     }
634     return true;
635 }
636 
637 lldb::thread_result_t
638 GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
639 {
640     GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
641     Error error;
642     ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
643 
644     if (connection)
645     {
646         // Do the listen on another thread so we can continue on...
647         if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
648             comm->SetConnection(NULL);
649     }
650     return NULL;
651 }
652 
653 Error
654 GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
655                                                  uint16_t in_port,
656                                                  lldb_private::ProcessLaunchInfo &launch_info,
657                                                  uint16_t &out_port)
658 {
659     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
660     if (log)
661         log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port);
662 
663     out_port = in_port;
664     Error error;
665     // If we locate debugserver, keep that located version around
666     static FileSpec g_debugserver_file_spec;
667 
668     char debugserver_path[PATH_MAX];
669     FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
670 
671     // Always check to see if we have an environment override for the path
672     // to the debugserver to use and use it if we do.
673     const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
674     if (env_debugserver_path)
675     {
676         debugserver_file_spec.SetFile (env_debugserver_path, false);
677         if (log)
678             log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
679     }
680     else
681         debugserver_file_spec = g_debugserver_file_spec;
682     bool debugserver_exists = debugserver_file_spec.Exists();
683     if (!debugserver_exists)
684     {
685         // The debugserver binary is in the LLDB.framework/Resources
686         // directory.
687         if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
688         {
689             debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
690             debugserver_exists = debugserver_file_spec.Exists();
691             if (debugserver_exists)
692             {
693                 if (log)
694                     log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
695 
696                 g_debugserver_file_spec = debugserver_file_spec;
697             }
698             else
699             {
700                 if (log)
701                     log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
702 
703                 g_debugserver_file_spec.Clear();
704                 debugserver_file_spec.Clear();
705             }
706         }
707     }
708 
709     if (debugserver_exists)
710     {
711         debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
712 
713         Args &debugserver_args = launch_info.GetArguments();
714         debugserver_args.Clear();
715         char arg_cstr[PATH_MAX];
716 
717         // Start args with "debugserver /file/path -r --"
718         debugserver_args.AppendArgument(debugserver_path);
719 
720         // If a host and port is supplied then use it
721         char host_and_port[128];
722         if (hostname)
723         {
724             snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
725             debugserver_args.AppendArgument(host_and_port);
726         }
727         else
728         {
729             host_and_port[0] = '\0';
730         }
731 
732         // use native registers, not the GDB registers
733         debugserver_args.AppendArgument("--native-regs");
734         // make debugserver run in its own session so signals generated by
735         // special terminal key sequences (^C) don't affect debugserver
736         debugserver_args.AppendArgument("--setsid");
737 
738         char named_pipe_path[PATH_MAX];
739         named_pipe_path[0] = '\0';
740 
741         bool listen = false;
742         if (host_and_port[0])
743         {
744             // Create a temporary file to get the stdout/stderr and redirect the
745             // output of the command into this file. We will later read this file
746             // if all goes well and fill the data into "command_output_ptr"
747 
748             if (in_port == 0)
749             {
750                 // Binding to port zero, we need to figure out what port it ends up
751                 // using using a named pipe...
752                 FileSpec tmpdir_file_spec;
753                 if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
754                 {
755                     tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
756                     strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
757                 }
758                 else
759                 {
760                     strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
761                 }
762 
763                 if (::mktemp (named_pipe_path))
764                 {
765 #if defined(_WIN32)
766                     if ( false )
767 #else
768                     if (::mkfifo(named_pipe_path, 0600) == 0)
769 #endif
770                     {
771                         debugserver_args.AppendArgument("--named-pipe");
772                         debugserver_args.AppendArgument(named_pipe_path);
773                     }
774                 }
775             }
776             else
777             {
778                 listen = true;
779             }
780         }
781         else
782         {
783             // No host and port given, so lets listen on our end and make the debugserver
784             // connect to us..
785             error = StartListenThread ("127.0.0.1", 0);
786             if (error.Fail())
787                 return error;
788 
789             ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
790             // Wait for 10 seconds to resolve the bound port
791             out_port = connection->GetListeningPort(10);
792             if (out_port > 0)
793             {
794                 char port_cstr[32];
795                 snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", out_port);
796                 // Send the host and port down that debugserver and specify an option
797                 // so that it connects back to the port we are listening to in this process
798                 debugserver_args.AppendArgument("--reverse-connect");
799                 debugserver_args.AppendArgument(port_cstr);
800             }
801             else
802             {
803                 error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
804                 return error;
805             }
806         }
807 
808         const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
809         if (env_debugserver_log_file)
810         {
811             ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
812             debugserver_args.AppendArgument(arg_cstr);
813         }
814 
815         const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
816         if (env_debugserver_log_flags)
817         {
818             ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
819             debugserver_args.AppendArgument(arg_cstr);
820         }
821 
822         // Close STDIN, STDOUT and STDERR. We might need to redirect them
823         // to "/dev/null" if we run into any problems.
824         launch_info.AppendCloseFileAction (STDIN_FILENO);
825         launch_info.AppendCloseFileAction (STDOUT_FILENO);
826         launch_info.AppendCloseFileAction (STDERR_FILENO);
827 
828         error = Host::LaunchProcess(launch_info);
829 
830         if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
831         {
832             if (named_pipe_path[0])
833             {
834                 File name_pipe_file;
835                 error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead);
836                 if (error.Success())
837                 {
838                     char port_cstr[256];
839                     port_cstr[0] = '\0';
840                     size_t num_bytes = sizeof(port_cstr);
841                     error = name_pipe_file.Read(port_cstr, num_bytes);
842                     assert (error.Success());
843                     assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
844                     out_port = Args::StringToUInt32(port_cstr, 0);
845                     name_pipe_file.Close();
846                 }
847                 FileSystem::Unlink(named_pipe_path);
848             }
849             else if (listen)
850             {
851 
852             }
853             else
854             {
855                 // Make sure we actually connect with the debugserver...
856                 JoinListenThread();
857             }
858         }
859     }
860     else
861     {
862         error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
863     }
864     return error;
865 }
866 
867 void
868 GDBRemoteCommunication::DumpHistory(Stream &strm)
869 {
870     m_history.Dump (strm);
871 }
872