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