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