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