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