xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (revision 144f3a9c90f8434b51b544042397718a3f09ac1f)
1 //===-- GDBRemoteCommunicationServer.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 "GDBRemoteCommunicationServer.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 #include "llvm/ADT/Triple.h"
17 #include "lldb/Interpreter/Args.h"
18 #include "lldb/Core/ConnectionFileDescriptor.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/State.h"
21 #include "lldb/Core/StreamString.h"
22 #include "lldb/Host/Endian.h"
23 #include "lldb/Host/Host.h"
24 #include "lldb/Host/TimeValue.h"
25 #include "lldb/Target/Process.h"
26 
27 // Project includes
28 #include "Utility/StringExtractorGDBRemote.h"
29 #include "ProcessGDBRemote.h"
30 #include "ProcessGDBRemoteLog.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 //----------------------------------------------------------------------
36 // GDBRemoteCommunicationServer constructor
37 //----------------------------------------------------------------------
38 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
39     GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
40     m_async_thread (LLDB_INVALID_HOST_THREAD),
41     m_process_launch_info (),
42     m_process_launch_error (),
43     m_proc_infos (),
44     m_proc_infos_index (0),
45     m_lo_port_num (0),
46     m_hi_port_num (0)
47 {
48 }
49 
50 //----------------------------------------------------------------------
51 // Destructor
52 //----------------------------------------------------------------------
53 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
54 {
55 }
56 
57 
58 //void *
59 //GDBRemoteCommunicationServer::AsyncThread (void *arg)
60 //{
61 //    GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
62 //
63 //    LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
64 //    if (log)
65 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
66 //
67 //    StringExtractorGDBRemote packet;
68 //
69 //    while ()
70 //    {
71 //        if (packet.
72 //    }
73 //
74 //    if (log)
75 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
76 //
77 //    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
78 //    return NULL;
79 //}
80 //
81 bool
82 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
83                                                         Error &error,
84                                                         bool &interrupt,
85                                                         bool &quit)
86 {
87     StringExtractorGDBRemote packet;
88     if (WaitForPacketWithTimeoutMicroSeconds(packet, timeout_usec))
89     {
90         const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
91         switch (packet_type)
92         {
93             case StringExtractorGDBRemote::eServerPacketType_nack:
94             case StringExtractorGDBRemote::eServerPacketType_ack:
95                 break;
96 
97             case StringExtractorGDBRemote::eServerPacketType_invalid:
98                 error.SetErrorString("invalid packet");
99                 quit = true;
100                 break;
101 
102             case StringExtractorGDBRemote::eServerPacketType_interrupt:
103                 error.SetErrorString("interrupt received");
104                 interrupt = true;
105                 break;
106 
107             case StringExtractorGDBRemote::eServerPacketType_unimplemented:
108                 return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
109 
110             case StringExtractorGDBRemote::eServerPacketType_A:
111                 return Handle_A (packet);
112 
113             case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
114                 return Handle_qfProcessInfo (packet);
115 
116             case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
117                 return Handle_qsProcessInfo (packet);
118 
119             case StringExtractorGDBRemote::eServerPacketType_qC:
120                 return Handle_qC (packet);
121 
122             case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
123                 return Handle_qHostInfo (packet);
124 
125             case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
126                 return Handle_qLaunchGDBServer (packet);
127 
128             case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
129                 return Handle_qLaunchSuccess (packet);
130 
131             case StringExtractorGDBRemote::eServerPacketType_qGroupName:
132                 return Handle_qGroupName (packet);
133 
134             case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
135                 return Handle_qProcessInfoPID (packet);
136 
137             case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
138                 return Handle_qSpeedTest (packet);
139 
140             case StringExtractorGDBRemote::eServerPacketType_qUserName:
141                 return Handle_qUserName (packet);
142 
143             case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
144                 return Handle_QEnvironment (packet);
145 
146             case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
147                 return Handle_QSetDisableASLR (packet);
148 
149             case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
150                 return Handle_QSetSTDIN (packet);
151 
152             case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
153                 return Handle_QSetSTDOUT (packet);
154 
155             case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
156                 return Handle_QSetSTDERR (packet);
157 
158             case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
159                 return Handle_QSetWorkingDir (packet);
160 
161             case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
162                 return Handle_QStartNoAckMode (packet);
163         }
164         return true;
165     }
166     else
167     {
168         if (!IsConnected())
169             error.SetErrorString("lost connection");
170         else
171             error.SetErrorString("timeout");
172     }
173 
174     return false;
175 }
176 
177 size_t
178 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
179 {
180     // TODO: Log the packet we aren't handling...
181     return SendPacket ("");
182 }
183 
184 size_t
185 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
186 {
187     char packet[16];
188     int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
189     assert (packet_len < sizeof(packet));
190     return SendPacket (packet, packet_len);
191 }
192 
193 
194 size_t
195 GDBRemoteCommunicationServer::SendOKResponse ()
196 {
197     return SendPacket ("OK");
198 }
199 
200 bool
201 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
202 {
203     return GetAck();
204 }
205 
206 bool
207 GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
208 {
209     StreamString response;
210 
211     // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
212 
213     ArchSpec host_arch (Host::GetArchitecture ());
214     const llvm::Triple &host_triple = host_arch.GetTriple();
215     response.PutCString("triple:");
216     response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
217     response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
218 
219     uint32_t cpu = host_arch.GetMachOCPUType();
220     uint32_t sub = host_arch.GetMachOCPUSubType();
221     if (cpu != LLDB_INVALID_CPUTYPE)
222         response.Printf ("cputype:%u;", cpu);
223     if (sub != LLDB_INVALID_CPUTYPE)
224         response.Printf ("cpusubtype:%u;", sub);
225 
226     switch (lldb::endian::InlHostByteOrder())
227     {
228     case eByteOrderBig:     response.PutCString ("endian:big;"); break;
229     case eByteOrderLittle:  response.PutCString ("endian:little;"); break;
230     case eByteOrderPDP:     response.PutCString ("endian:pdp;"); break;
231     default:                response.PutCString ("endian:unknown;"); break;
232     }
233 
234     uint32_t major = UINT32_MAX;
235     uint32_t minor = UINT32_MAX;
236     uint32_t update = UINT32_MAX;
237     if (Host::GetOSVersion (major, minor, update))
238     {
239         if (major != UINT32_MAX)
240         {
241             response.Printf("os_version:%u", major);
242             if (minor != UINT32_MAX)
243             {
244                 response.Printf(".%u", minor);
245                 if (update != UINT32_MAX)
246                     response.Printf(".%u", update);
247             }
248             response.PutChar(';');
249         }
250     }
251 
252     std::string s;
253     if (Host::GetOSBuildString (s))
254     {
255         response.PutCString ("os_build:");
256         response.PutCStringAsRawHex8(s.c_str());
257         response.PutChar(';');
258     }
259     if (Host::GetOSKernelDescription (s))
260     {
261         response.PutCString ("os_kernel:");
262         response.PutCStringAsRawHex8(s.c_str());
263         response.PutChar(';');
264     }
265     if (Host::GetHostname (s))
266     {
267         response.PutCString ("hostname:");
268         response.PutCStringAsRawHex8(s.c_str());
269         response.PutChar(';');
270     }
271 
272     return SendPacket (response) > 0;
273 }
274 
275 static void
276 CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response)
277 {
278     response.Printf ("pid:%i;ppid:%i;uid:%i;gid:%i;euid:%i;egid:%i;",
279                      proc_info.GetProcessID(),
280                      proc_info.GetParentProcessID(),
281                      proc_info.GetUserID(),
282                      proc_info.GetGroupID(),
283                      proc_info.GetEffectiveUserID(),
284                      proc_info.GetEffectiveGroupID());
285     response.PutCString ("name:");
286     response.PutCStringAsRawHex8(proc_info.GetName());
287     response.PutChar(';');
288     const ArchSpec &proc_arch = proc_info.GetArchitecture();
289     if (proc_arch.IsValid())
290     {
291         const llvm::Triple &proc_triple = proc_arch.GetTriple();
292         response.PutCString("triple:");
293         response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
294         response.PutChar(';');
295     }
296 }
297 
298 bool
299 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
300 {
301     // Packet format: "qProcessInfoPID:%i" where %i is the pid
302     packet.SetFilePos(::strlen ("qProcessInfoPID:"));
303     lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
304     if (pid != LLDB_INVALID_PROCESS_ID)
305     {
306         ProcessInstanceInfo proc_info;
307         if (Host::GetProcessInfo(pid, proc_info))
308         {
309             StreamString response;
310             CreateProcessInfoResponse (proc_info, response);
311             return SendPacket (response);
312         }
313     }
314     return SendErrorResponse (1);
315 }
316 
317 bool
318 GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
319 {
320     m_proc_infos_index = 0;
321     m_proc_infos.Clear();
322 
323     ProcessInstanceInfoMatch match_info;
324     packet.SetFilePos(::strlen ("qfProcessInfo"));
325     if (packet.GetChar() == ':')
326     {
327 
328         std::string key;
329         std::string value;
330         while (packet.GetNameColonValue(key, value))
331         {
332             bool success = true;
333             if (key.compare("name") == 0)
334             {
335                 StringExtractor extractor;
336                 extractor.GetStringRef().swap(value);
337                 extractor.GetHexByteString (value);
338                 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
339             }
340             else if (key.compare("name_match") == 0)
341             {
342                 if (value.compare("equals") == 0)
343                 {
344                     match_info.SetNameMatchType (eNameMatchEquals);
345                 }
346                 else if (value.compare("starts_with") == 0)
347                 {
348                     match_info.SetNameMatchType (eNameMatchStartsWith);
349                 }
350                 else if (value.compare("ends_with") == 0)
351                 {
352                     match_info.SetNameMatchType (eNameMatchEndsWith);
353                 }
354                 else if (value.compare("contains") == 0)
355                 {
356                     match_info.SetNameMatchType (eNameMatchContains);
357                 }
358                 else if (value.compare("regex") == 0)
359                 {
360                     match_info.SetNameMatchType (eNameMatchRegularExpression);
361                 }
362                 else
363                 {
364                     success = false;
365                 }
366             }
367             else if (key.compare("pid") == 0)
368             {
369                 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
370             }
371             else if (key.compare("parent_pid") == 0)
372             {
373                 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
374             }
375             else if (key.compare("uid") == 0)
376             {
377                 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
378             }
379             else if (key.compare("gid") == 0)
380             {
381                 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
382             }
383             else if (key.compare("euid") == 0)
384             {
385                 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
386             }
387             else if (key.compare("egid") == 0)
388             {
389                 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
390             }
391             else if (key.compare("all_users") == 0)
392             {
393                 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
394             }
395             else if (key.compare("triple") == 0)
396             {
397                 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
398             }
399             else
400             {
401                 success = false;
402             }
403 
404             if (!success)
405                 return SendErrorResponse (2);
406         }
407     }
408 
409     if (Host::FindProcesses (match_info, m_proc_infos))
410     {
411         // We found something, return the first item by calling the get
412         // subsequent process info packet handler...
413         return Handle_qsProcessInfo (packet);
414     }
415     return SendErrorResponse (3);
416 }
417 
418 bool
419 GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
420 {
421     if (m_proc_infos_index < m_proc_infos.GetSize())
422     {
423         StreamString response;
424         CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
425         ++m_proc_infos_index;
426         return SendPacket (response);
427     }
428     return SendErrorResponse (4);
429 }
430 
431 bool
432 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
433 {
434     // Packet format: "qUserName:%i" where %i is the uid
435     packet.SetFilePos(::strlen ("qUserName:"));
436     uint32_t uid = packet.GetU32 (UINT32_MAX);
437     if (uid != UINT32_MAX)
438     {
439         std::string name;
440         if (Host::GetUserName (uid, name))
441         {
442             StreamString response;
443             response.PutCStringAsRawHex8 (name.c_str());
444             return SendPacket (response);
445         }
446     }
447     return SendErrorResponse (5);
448 
449 }
450 
451 bool
452 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
453 {
454     // Packet format: "qGroupName:%i" where %i is the gid
455     packet.SetFilePos(::strlen ("qGroupName:"));
456     uint32_t gid = packet.GetU32 (UINT32_MAX);
457     if (gid != UINT32_MAX)
458     {
459         std::string name;
460         if (Host::GetGroupName (gid, name))
461         {
462             StreamString response;
463             response.PutCStringAsRawHex8 (name.c_str());
464             return SendPacket (response);
465         }
466     }
467     return SendErrorResponse (6);
468 }
469 
470 bool
471 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
472 {
473     packet.SetFilePos(::strlen ("qSpeedTest:"));
474 
475     std::string key;
476     std::string value;
477     bool success = packet.GetNameColonValue(key, value);
478     if (success && key.compare("response_size") == 0)
479     {
480         uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
481         if (success)
482         {
483             if (response_size == 0)
484                 return SendOKResponse();
485             StreamString response;
486             uint32_t bytes_left = response_size;
487             response.PutCString("data:");
488             while (bytes_left > 0)
489             {
490                 if (bytes_left >= 26)
491                 {
492                     response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
493                     bytes_left -= 26;
494                 }
495                 else
496                 {
497                     response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
498                     bytes_left = 0;
499                 }
500             }
501             return SendPacket (response);
502         }
503     }
504     return SendErrorResponse (7);
505 }
506 
507 
508 static void *
509 AcceptPortFromInferior (void *arg)
510 {
511     const char *connect_url = (const char *)arg;
512     ConnectionFileDescriptor file_conn;
513     Error error;
514     if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess)
515     {
516         char pid_str[256];
517         ::memset (pid_str, 0, sizeof(pid_str));
518         ConnectionStatus status;
519         const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), NULL, status, NULL);
520         if (pid_str_len > 0)
521         {
522             int pid = atoi (pid_str);
523             return (void *)(intptr_t)pid;
524         }
525     }
526     return NULL;
527 }
528 //
529 //static bool
530 //WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds)
531 //{
532 //    const int time_delta_usecs = 100000;
533 //    const int num_retries = timeout_in_seconds/time_delta_usecs;
534 //    for (int i=0; i<num_retries; i++)
535 //    {
536 //        struct proc_bsdinfo bsd_info;
537 //        int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO,
538 //                                    (uint64_t) 0,
539 //                                    &bsd_info,
540 //                                    PROC_PIDTBSDINFO_SIZE);
541 //
542 //        switch (error)
543 //        {
544 //            case EINVAL:
545 //            case ENOTSUP:
546 //            case ESRCH:
547 //            case EPERM:
548 //                return false;
549 //
550 //            default:
551 //                break;
552 //
553 //            case 0:
554 //                if (bsd_info.pbi_status == SSTOP)
555 //                    return true;
556 //        }
557 //        ::usleep (time_delta_usecs);
558 //    }
559 //    return false;
560 //}
561 
562 bool
563 GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
564 {
565     // The 'A' packet is the most over designed packet ever here with
566     // redundant argument indexes, redundant argument lengths and needed hex
567     // encoded argument string values. Really all that is needed is a comma
568     // separated hex encoded argument value list, but we will stay true to the
569     // documented version of the 'A' packet here...
570 
571     packet.SetFilePos(1); // Skip the 'A'
572     bool success = true;
573     while (success && packet.GetBytesLeft() > 0)
574     {
575         // Decode the decimal argument string length. This length is the
576         // number of hex nibbles in the argument string value.
577         const uint32_t arg_len = packet.GetU32(UINT32_MAX);
578         if (arg_len == UINT32_MAX)
579             success = false;
580         else
581         {
582             // Make sure the argument hex string length is followed by a comma
583             if (packet.GetChar() != ',')
584                 success = false;
585             else
586             {
587                 // Decode the argument index. We ignore this really becuase
588                 // who would really send down the arguments in a random order???
589                 const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
590                 if (arg_idx == UINT32_MAX)
591                     success = false;
592                 else
593                 {
594                     // Make sure the argument index is followed by a comma
595                     if (packet.GetChar() != ',')
596                         success = false;
597                     else
598                     {
599                         // Decode the argument string value from hex bytes
600                         // back into a UTF8 string and make sure the length
601                         // matches the one supplied in the packet
602                         std::string arg;
603                         if (packet.GetHexByteString(arg) != (arg_len / 2))
604                             success = false;
605                         else
606                         {
607                             // If there are any bytes lft
608                             if (packet.GetBytesLeft())
609                             {
610                                 if (packet.GetChar() != ',')
611                                     success = false;
612                             }
613 
614                             if (success)
615                             {
616                                 if (arg_idx == 0)
617                                     m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
618                                 m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
619                             }
620                         }
621                     }
622                 }
623             }
624         }
625     }
626 
627     if (success)
628     {
629         m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
630         m_process_launch_error = Host::LaunchProcess (m_process_launch_info);
631         if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
632         {
633             return SendOKResponse ();
634         }
635     }
636     return SendErrorResponse (8);
637 }
638 
639 bool
640 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
641 {
642     lldb::pid_t pid = m_process_launch_info.GetProcessID();
643     StreamString response;
644     response.Printf("QC%x", pid);
645     if (m_is_platform)
646     {
647         // If we launch a process and this GDB server is acting as a platform,
648         // then we need to clear the process launch state so we can start
649         // launching another process. In order to launch a process a bunch or
650         // packets need to be sent: environment packets, working directory,
651         // disable ASLR, and many more settings. When we launch a process we
652         // then need to know when to clear this information. Currently we are
653         // selecting the 'qC' packet as that packet which seems to make the most
654         // sense.
655         if (pid != LLDB_INVALID_PROCESS_ID)
656         {
657             m_process_launch_info.Clear();
658         }
659     }
660     return SendPacket (response);
661 }
662 
663 bool
664 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
665 {
666     // Spawn a local debugserver as a platform so we can then attach or launch
667     // a process...
668 
669     if (m_is_platform)
670     {
671         // Sleep and wait a bit for debugserver to start to listen...
672         ConnectionFileDescriptor file_conn;
673         char connect_url[PATH_MAX];
674         Error error;
675         char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX";
676         if (::mktemp (unix_socket_name) == NULL)
677         {
678             error.SetErrorString ("failed to make temporary path for a unix socket");
679         }
680         else
681         {
682             ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name);
683             // Spawn a new thread to accept the port that gets bound after
684             // binding to port 0 (zero).
685             lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name,
686                                                                AcceptPortFromInferior,
687                                                                connect_url,
688                                                                &error);
689 
690             if (IS_VALID_LLDB_HOST_THREAD(accept_thread))
691             {
692                 // Spawn a debugserver and try to get
693                 ProcessLaunchInfo debugserver_launch_info;
694                 error = StartDebugserverProcess ("localhost:0",
695                                                  unix_socket_name,
696                                                  debugserver_launch_info);
697 
698                 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
699                 if (error.Success())
700                 {
701                     bool success = false;
702 
703                     thread_result_t accept_thread_result = NULL;
704                     if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error))
705                     {
706                         if (accept_thread_result)
707                         {
708                             uint16_t port = (intptr_t)accept_thread_result;
709                             char response[256];
710                             const int response_len = ::snprintf (response, sizeof(response), "pid:%u;port:%u;", debugserver_pid, port);
711                             assert (response_len < sizeof(response));
712                             //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
713                             success = SendPacket (response, response_len) > 0;
714                         }
715                     }
716                     ::unlink (unix_socket_name);
717 
718                     if (!success)
719                     {
720                         if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
721                             ::kill (debugserver_pid, SIGINT);
722                     }
723                     return success;
724                 }
725             }
726         }
727     }
728     return SendErrorResponse (13);
729 }
730 
731 bool
732 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
733 {
734     if (m_process_launch_error.Success())
735         return SendOKResponse();
736     StreamString response;
737     response.PutChar('E');
738     response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
739     return SendPacket (response);
740 }
741 
742 bool
743 GDBRemoteCommunicationServer::Handle_QEnvironment  (StringExtractorGDBRemote &packet)
744 {
745     packet.SetFilePos(::strlen ("QEnvironment:"));
746     const uint32_t bytes_left = packet.GetBytesLeft();
747     if (bytes_left > 0)
748     {
749         m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
750         return SendOKResponse ();
751     }
752     return SendErrorResponse (9);
753 }
754 
755 bool
756 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
757 {
758     packet.SetFilePos(::strlen ("QSetDisableASLR:"));
759     if (packet.GetU32(0))
760         m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
761     else
762         m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
763     return SendOKResponse ();
764 }
765 
766 bool
767 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
768 {
769     packet.SetFilePos(::strlen ("QSetWorkingDir:"));
770     std::string path;
771     packet.GetHexByteString(path);
772     m_process_launch_info.SwapWorkingDirectory (path);
773     return SendOKResponse ();
774 }
775 
776 bool
777 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
778 {
779     packet.SetFilePos(::strlen ("QSetSTDIN:"));
780     ProcessLaunchInfo::FileAction file_action;
781     std::string path;
782     packet.GetHexByteString(path);
783     const bool read = false;
784     const bool write = true;
785     if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
786     {
787         m_process_launch_info.AppendFileAction(file_action);
788         return SendOKResponse ();
789     }
790     return SendErrorResponse (10);
791 }
792 
793 bool
794 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
795 {
796     packet.SetFilePos(::strlen ("QSetSTDOUT:"));
797     ProcessLaunchInfo::FileAction file_action;
798     std::string path;
799     packet.GetHexByteString(path);
800     const bool read = true;
801     const bool write = false;
802     if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
803     {
804         m_process_launch_info.AppendFileAction(file_action);
805         return SendOKResponse ();
806     }
807     return SendErrorResponse (11);
808 }
809 
810 bool
811 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
812 {
813     packet.SetFilePos(::strlen ("QSetSTDERR:"));
814     ProcessLaunchInfo::FileAction file_action;
815     std::string path;
816     packet.GetHexByteString(path);
817     const bool read = true;
818     const bool write = true;
819     if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
820     {
821         m_process_launch_info.AppendFileAction(file_action);
822         return SendOKResponse ();
823     }
824     return SendErrorResponse (12);
825 }
826 
827 bool
828 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
829 {
830     // Send response first before changing m_send_acks to we ack this packet
831     SendOKResponse ();
832     m_send_acks = false;
833     return true;
834 }
835