//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "GDBRemoteCommunication.h"

// C Includes
#include <limits.h>
#include <string.h>
#include <sys/stat.h>

// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "llvm/ADT/SmallString.h"

// Project includes
#include "ProcessGDBRemoteLog.h"

#if defined(__APPLE__)
# define DEBUGSERVER_BASENAME    "debugserver"
#else
# define DEBUGSERVER_BASENAME    "lldb-server"
#endif

#if defined (HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif

#if defined (HAVE_LIBZ)
#include <zlib.h>
#endif

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;

GDBRemoteCommunication::History::History (uint32_t size) :
    m_packets(),
    m_curr_idx (0),
    m_total_packet_count (0),
    m_dumped_to_log (false)
{
    m_packets.resize(size);
}

GDBRemoteCommunication::History::~History ()
{
}

void
GDBRemoteCommunication::History::AddPacket (char packet_char,
                                            PacketType type,
                                            uint32_t bytes_transmitted)
{
    const size_t size = m_packets.size();
    if (size > 0)
    {
        const uint32_t idx = GetNextIndex();
        m_packets[idx].packet.assign (1, packet_char);
        m_packets[idx].type = type;
        m_packets[idx].bytes_transmitted = bytes_transmitted;
        m_packets[idx].packet_idx = m_total_packet_count;
        m_packets[idx].tid = Host::GetCurrentThreadID();
    }
}

void
GDBRemoteCommunication::History::AddPacket (const std::string &src,
                                            uint32_t src_len,
                                            PacketType type,
                                            uint32_t bytes_transmitted)
{
    const size_t size = m_packets.size();
    if (size > 0)
    {
        const uint32_t idx = GetNextIndex();
        m_packets[idx].packet.assign (src, 0, src_len);
        m_packets[idx].type = type;
        m_packets[idx].bytes_transmitted = bytes_transmitted;
        m_packets[idx].packet_idx = m_total_packet_count;
        m_packets[idx].tid = Host::GetCurrentThreadID();
    }
}

void
GDBRemoteCommunication::History::Dump (Stream &strm) const
{
    const uint32_t size = GetNumPacketsInHistory ();
    const uint32_t first_idx = GetFirstSavedPacketIndex ();
    const uint32_t stop_idx = m_curr_idx + size;
    for (uint32_t i = first_idx;  i < stop_idx; ++i)
    {
        const uint32_t idx = NormalizeIndex (i);
        const Entry &entry = m_packets[idx];
        if (entry.type == ePacketTypeInvalid || entry.packet.empty())
            break;
        strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
                     entry.packet_idx,
                     entry.tid,
                     entry.bytes_transmitted,
                     (entry.type == ePacketTypeSend) ? "send" : "read",
                     entry.packet.c_str());
    }
}

void
GDBRemoteCommunication::History::Dump (Log *log) const
{
    if (log && !m_dumped_to_log)
    {
        m_dumped_to_log = true;
        const uint32_t size = GetNumPacketsInHistory ();
        const uint32_t first_idx = GetFirstSavedPacketIndex ();
        const uint32_t stop_idx = m_curr_idx + size;
        for (uint32_t i = first_idx;  i < stop_idx; ++i)
        {
            const uint32_t idx = NormalizeIndex (i);
            const Entry &entry = m_packets[idx];
            if (entry.type == ePacketTypeInvalid || entry.packet.empty())
                break;
            log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
                         entry.packet_idx,
                         entry.tid,
                         entry.bytes_transmitted,
                         (entry.type == ePacketTypeSend) ? "send" : "read",
                         entry.packet.c_str());
        }
    }
}

//----------------------------------------------------------------------
// GDBRemoteCommunication constructor
//----------------------------------------------------------------------
GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, 
                                               const char *listener_name) :
    Communication(comm_name),
#ifdef LLDB_CONFIGURATION_DEBUG
    m_packet_timeout (1000),
#else
    m_packet_timeout (1),
#endif
    m_echo_number(0),
    m_supports_qEcho (eLazyBoolCalculate),
    m_sequence_mutex (Mutex::eMutexTypeRecursive),
    m_public_is_running (false),
    m_private_is_running (false),
    m_history (512),
    m_send_acks (true),
    m_compression_type (CompressionType::None),
    m_listen_url ()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
GDBRemoteCommunication::~GDBRemoteCommunication()
{
    if (IsConnected())
    {
        Disconnect();
    }

    // Stop the communications read thread which is used to parse all
    // incoming packets.  This function will block until the read
    // thread returns.
    if (m_read_thread_enabled)
        StopReadThread();
}

char
GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
{
    int checksum = 0;

    for (size_t i = 0; i < payload_length; ++i)
        checksum += payload[i];

    return checksum & 255;
}

size_t
GDBRemoteCommunication::SendAck ()
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
    ConnectionStatus status = eConnectionStatusSuccess;
    char ch = '+';
    const size_t bytes_written = Write (&ch, 1, status, NULL);
    if (log)
        log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
    m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
    return bytes_written;
}

size_t
GDBRemoteCommunication::SendNack ()
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
    ConnectionStatus status = eConnectionStatusSuccess;
    char ch = '-';
    const size_t bytes_written = Write (&ch, 1, status, NULL);
    if (log)
        log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
    m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
    return bytes_written;
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
{
    Mutex::Locker locker(m_sequence_mutex);
    return SendPacketNoLock (payload, payload_length);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
{
    if (IsConnected())
    {
        StreamString packet(0, 4, eByteOrderBig);

        packet.PutChar('$');
        packet.Write (payload, payload_length);
        packet.PutChar('#');
        packet.PutHex8(CalculcateChecksum (payload, payload_length));

        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
        ConnectionStatus status = eConnectionStatusSuccess;
        const char *packet_data = packet.GetData();
        const size_t packet_length = packet.GetSize();
        size_t bytes_written = Write (packet_data, packet_length, status, NULL);
        if (log)
        {
            size_t binary_start_offset = 0;
            if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0)
            {
                const char *first_comma = strchr(packet_data, ',');
                if (first_comma)
                {
                    const char *second_comma = strchr(first_comma + 1, ',');
                    if (second_comma)
                        binary_start_offset = second_comma - packet_data + 1;
                }
            }

            // If logging was just enabled and we have history, then dump out what
            // we have to the log so we get the historical context. The Dump() call that
            // logs all of the packet will set a boolean so that we don't dump this more
            // than once
            if (!m_history.DidDumpToLog ())
                m_history.Dump (log);

            if (binary_start_offset)
            {
                StreamString strm;
                // Print non binary data header
                strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data);
                const uint8_t *p;
                // Print binary data exactly as sent
                for (p = (const uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p)
                    strm.Printf("\\x%2.2x", *p);
                // Print the checksum
                strm.Printf("%*s", (int)3, p);
                log->PutCString(strm.GetString().c_str());
            }
            else
                log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data);
        }

        m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written);


        if (bytes_written == packet_length)
        {
            if (GetSendAcks ())
                return GetAck ();
            else
                return PacketResult::Success;
        }
        else
        {
            if (log)
                log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data);
        }
    }
    return PacketResult::ErrorSendFailed;
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::GetAck ()
{
    StringExtractorGDBRemote packet;
    PacketResult result = ReadPacket (packet, GetPacketTimeoutInMicroSeconds (), false);
    if (result == PacketResult::Success)
    {
        if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
            return PacketResult::Success;
        else
            return PacketResult::ErrorSendAck;
    }
    return result;
}

bool
GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
{
    if (IsRunning())
        return locker.TryLock (m_sequence_mutex, failure_message);

    locker.Lock (m_sequence_mutex);
    return true;
}


bool
GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
{
    return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout)
{
   if (m_read_thread_enabled)
       return PopPacketFromQueue (response, timeout_usec);
   else
       return WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec, sync_on_timeout);
}


// This function is called when a packet is requested.
// A whole packet is popped from the packet queue and returned to the caller.
// Packets are placed into this queue from the communication read thread.
// See GDBRemoteCommunication::AppendBytesToCache.
GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec)
{
    // Calculate absolute timeout value
    TimeValue timeout = TimeValue::Now();
    timeout.OffsetWithMicroSeconds(timeout_usec);

    do
    {
        // scope for the mutex
        {
            // lock down the packet queue
            Mutex::Locker locker(m_packet_queue_mutex);

            // Wait on condition variable.
            if (m_packet_queue.size() == 0)
                m_condition_queue_not_empty.Wait(m_packet_queue_mutex, &timeout);

            if (m_packet_queue.size() > 0)
            {
                // get the front element of the queue
                response = m_packet_queue.front();

                // remove the front element
                m_packet_queue.pop();

                // we got a packet
                return PacketResult::Success;
            }
         }

         // Disconnected
         if (!IsConnected())
             return PacketResult::ErrorDisconnected;

      // Loop while not timed out
    } while (TimeValue::Now() < timeout);

    return PacketResult::ErrorReplyTimeout;
}


GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec, bool sync_on_timeout)
{
    uint8_t buffer[8192];
    Error error;

    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));

    // Check for a packet from our cache first without trying any reading...
    if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
        return PacketResult::Success;

    bool timed_out = false;
    bool disconnected = false;
    while (IsConnected() && !timed_out)
    {
        lldb::ConnectionStatus status = eConnectionStatusNoConnection;
        size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
        
        if (log)
            log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
                         __PRETTY_FUNCTION__,
                         timeout_usec, 
                         Communication::ConnectionStatusAsCString (status),
                         error.AsCString(), 
                         (uint64_t)bytes_read);

        if (bytes_read > 0)
        {
            if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
                return PacketResult::Success;
        }
        else
        {
            switch (status)
            {
            case eConnectionStatusTimedOut:
            case eConnectionStatusInterrupted:
                if (sync_on_timeout)
                {
                    //------------------------------------------------------------------
                    /// Sync the remote GDB server and make sure we get a response that
                    /// corresponds to what we send.
                    ///
                    /// Sends a "qEcho" packet and makes sure it gets the exact packet
                    /// echoed back. If the qEcho packet isn't supported, we send a qC
                    /// packet and make sure we get a valid thread ID back. We use the
                    /// "qC" packet since its response if very unique: is responds with
                    /// "QC%x" where %x is the thread ID of the current thread. This
                    /// makes the response unique enough from other packet responses to
                    /// ensure we are back on track.
                    ///
                    /// This packet is needed after we time out sending a packet so we
                    /// can ensure that we are getting the response for the packet we
                    /// are sending. There are no sequence IDs in the GDB remote
                    /// protocol (there used to be, but they are not supported anymore)
                    /// so if you timeout sending packet "abc", you might then send
                    /// packet "cde" and get the response for the previous "abc" packet.
                    /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
                    /// many responses for packets can look like responses for other
                    /// packets. So if we timeout, we need to ensure that we can get
                    /// back on track. If we can't get back on track, we must
                    /// disconnect.
                    //------------------------------------------------------------------
                    bool sync_success = false;
                    bool got_actual_response = false;
                    // We timed out, we need to sync back up with the
                    char echo_packet[32];
                    int echo_packet_len = 0;
                    RegularExpression response_regex;

                    if (m_supports_qEcho == eLazyBoolYes)
                    {
                        echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qEcho:%u", ++m_echo_number);
                        std::string regex_str = "^";
                        regex_str += echo_packet;
                        regex_str += "$";
                        response_regex.Compile(regex_str.c_str());
                    }
                    else
                    {
                        echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qC");
                        response_regex.Compile("^QC[0-9A-Fa-f]+$");
                    }

                    PacketResult echo_packet_result = SendPacketNoLock (echo_packet, echo_packet_len);
                    if (echo_packet_result == PacketResult::Success)
                    {
                        const uint32_t max_retries = 3;
                        uint32_t successful_responses = 0;
                        for (uint32_t i=0; i<max_retries; ++i)
                        {
                            StringExtractorGDBRemote echo_response;
                            echo_packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (echo_response, timeout_usec, false);
                            if (echo_packet_result == PacketResult::Success)
                            {
                                ++successful_responses;
                                if (response_regex.Execute(echo_response.GetStringRef().c_str()))
                                {
                                    sync_success = true;
                                    break;
                                }
                                else if (successful_responses == 1)
                                {
                                    // We got something else back as the first successful response, it probably is
                                    // the  response to the packet we actually wanted, so copy it over if this
                                    // is the first success and continue to try to get the qEcho response
                                    packet = echo_response;
                                    got_actual_response = true;
                                }
                            }
                            else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
                                continue;   // Packet timed out, continue waiting for a response
                            else
                                break;      // Something else went wrong getting the packet back, we failed and are done trying
                        }
                    }

                    // We weren't able to sync back up with the server, we must abort otherwise
                    // all responses might not be from the right packets...
                    if (sync_success)
                    {
                        // We timed out, but were able to recover
                        if (got_actual_response)
                        {
                            // We initially timed out, but we did get a response that came in before the successful
                            // reply to our qEcho packet, so lets say everything is fine...
                            return PacketResult::Success;
                        }
                    }
                    else
                    {
                        disconnected = true;
                        Disconnect();
                    }
                }
                timed_out = true;
                break;
            case eConnectionStatusSuccess:
                //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
                break;
                
            case eConnectionStatusEndOfFile:
            case eConnectionStatusNoConnection:
            case eConnectionStatusLostConnection:
            case eConnectionStatusError:
                disconnected = true;
                Disconnect();
                break;
            }
        }
    }
    packet.Clear ();
    if (disconnected)
        return PacketResult::ErrorDisconnected;
    if (timed_out)
        return PacketResult::ErrorReplyTimeout;
    else
        return PacketResult::ErrorReplyFailed;
}

bool
GDBRemoteCommunication::DecompressPacket ()
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));

    if (!CompressionIsEnabled())
        return true;

    size_t pkt_size = m_bytes.size();

    // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating
    // an unsupported packet.  Anything less than 5 characters, it's definitely not a compressed packet.
    if (pkt_size < 5)
        return true;

    if (m_bytes[0] != '$' && m_bytes[0] != '%')
        return true;
    if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
        return true;

    size_t hash_mark_idx = m_bytes.find ('#');
    if (hash_mark_idx == std::string::npos)
        return true;
    if (hash_mark_idx + 2 >= m_bytes.size())
        return true;

    if (!::isxdigit (m_bytes[hash_mark_idx + 1]) || !::isxdigit (m_bytes[hash_mark_idx + 2]))
        return true;

    size_t content_length = pkt_size - 5;    // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
    size_t content_start = 2;                // The first character of the compressed/not-compressed text of the packet
    size_t checksum_idx = hash_mark_idx + 1; // The first character of the two hex checksum characters

    // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain multiple packets.
    // size_of_first_packet is the size of the initial packet which we'll replace with the decompressed
    // version of, leaving the rest of m_bytes unmodified.
    size_t size_of_first_packet = hash_mark_idx + 3; 

    // Compressed packets ("$C") start with a base10 number which is the size of the uncompressed payload,
    // then a : and then the compressed data.  e.g. $C1024:<binary>#00
    // Update content_start and content_length to only include the <binary> part of the packet.

    uint64_t decompressed_bufsize = ULONG_MAX;
    if (m_bytes[1] == 'C')
    {
        size_t i = content_start;
        while (i < hash_mark_idx && isdigit(m_bytes[i]))
            i++;
        if (i < hash_mark_idx && m_bytes[i] == ':')
        {
            i++;
            content_start = i;
            content_length = hash_mark_idx - content_start;
            std::string bufsize_str (m_bytes.data() + 2, i - 2 - 1);
            errno = 0;
            decompressed_bufsize = ::strtoul (bufsize_str.c_str(), NULL, 10);
            if (errno != 0 || decompressed_bufsize == ULONG_MAX)
            {
                m_bytes.erase (0, size_of_first_packet);
                return false;
            }
        }
    }

    if (GetSendAcks ())
    {
        char packet_checksum_cstr[3];
        packet_checksum_cstr[0] = m_bytes[checksum_idx];
        packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
        packet_checksum_cstr[2] = '\0';
        long packet_checksum = strtol (packet_checksum_cstr, NULL, 16);

        long actual_checksum = CalculcateChecksum (m_bytes.data() + 1, hash_mark_idx - 1);
        bool success = packet_checksum == actual_checksum;
        if (!success)
        {
            if (log)
                log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 
                             (int)(pkt_size), 
                             m_bytes.c_str(),
                             (uint8_t)packet_checksum,
                             (uint8_t)actual_checksum);
        }
        // Send the ack or nack if needed
        if (!success)
        {
            SendNack();
            m_bytes.erase (0, size_of_first_packet);
            return false;
        }
        else
        {
            SendAck();
        }
    }

    if (m_bytes[1] == 'N')
    {
        // This packet was not compressed -- delete the 'N' character at the 
        // start and the packet may be processed as-is.
        m_bytes.erase(1, 1);
        return true;
    }

    // Reverse the gdb-remote binary escaping that was done to the compressed text to
    // guard characters like '$', '#', '}', etc.
    std::vector<uint8_t> unescaped_content;
    unescaped_content.reserve (content_length);
    size_t i = content_start;
    while (i < hash_mark_idx)
    {
        if (m_bytes[i] == '}')
        {
            i++;
            unescaped_content.push_back (m_bytes[i] ^ 0x20);
        }
        else
        {
            unescaped_content.push_back (m_bytes[i]);
        }
        i++;
    }

    uint8_t *decompressed_buffer = nullptr;
    size_t decompressed_bytes = 0;

    if (decompressed_bufsize != ULONG_MAX)
    {
        decompressed_buffer = (uint8_t *) malloc (decompressed_bufsize + 1);
        if (decompressed_buffer == nullptr)
        {
            m_bytes.erase (0, size_of_first_packet);
            return false;
        }

    }

#if defined (HAVE_LIBCOMPRESSION)
    // libcompression is weak linked so check that compression_decode_buffer() is available
    if (compression_decode_buffer != NULL &&
        (m_compression_type == CompressionType::ZlibDeflate 
         || m_compression_type == CompressionType::LZFSE
         || m_compression_type == CompressionType::LZ4))
    {
        compression_algorithm compression_type;
        if (m_compression_type == CompressionType::ZlibDeflate)
            compression_type = COMPRESSION_ZLIB;
        else if (m_compression_type == CompressionType::LZFSE)
            compression_type = COMPRESSION_LZFSE;
        else if (m_compression_type == CompressionType::LZ4)
            compression_type = COMPRESSION_LZ4_RAW;
        else if (m_compression_type == CompressionType::LZMA)
            compression_type = COMPRESSION_LZMA;


        // If we have the expected size of the decompressed payload, we can allocate
        // the right-sized buffer and do it.  If we don't have that information, we'll
        // need to try decoding into a big buffer and if the buffer wasn't big enough,
        // increase it and try again.

        if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr)
        {
            decompressed_bytes = compression_decode_buffer (decompressed_buffer, decompressed_bufsize + 10 ,
                                                        (uint8_t*) unescaped_content.data(),
                                                        unescaped_content.size(),
                                                        NULL,
                                                        compression_type);
        }
    }
#endif

#if defined (HAVE_LIBZ)
    if (decompressed_bytes == 0 
        && decompressed_bufsize != ULONG_MAX
        && decompressed_buffer != nullptr 
        && m_compression_type == CompressionType::ZlibDeflate)
    {
        z_stream stream;
        memset (&stream, 0, sizeof (z_stream));
        stream.next_in = (Bytef *) unescaped_content.data();
        stream.avail_in = (uInt) unescaped_content.size();
        stream.total_in = 0;
        stream.next_out = (Bytef *) decompressed_buffer;
        stream.avail_out = decompressed_bufsize;
        stream.total_out = 0;
        stream.zalloc = Z_NULL;
        stream.zfree = Z_NULL;
        stream.opaque = Z_NULL;

        if (inflateInit2 (&stream, -15) == Z_OK)
        {
            int status = inflate (&stream, Z_NO_FLUSH);
            inflateEnd (&stream);
            if (status == Z_STREAM_END)
            {
                decompressed_bytes = stream.total_out;
            }
        }
    }
#endif

    if (decompressed_bytes == 0 || decompressed_buffer == nullptr)
    {
        if (decompressed_buffer)
            free (decompressed_buffer);
        m_bytes.erase (0, size_of_first_packet);
        return false;
    }

    std::string new_packet;
    new_packet.reserve (decompressed_bytes + 6);
    new_packet.push_back (m_bytes[0]);
    new_packet.append ((const char *) decompressed_buffer, decompressed_bytes);
    new_packet.push_back ('#');
    if (GetSendAcks ())
    {
        uint8_t decompressed_checksum = CalculcateChecksum ((const char *) decompressed_buffer, decompressed_bytes);
        char decompressed_checksum_str[3];
        snprintf (decompressed_checksum_str, 3, "%02x", decompressed_checksum);
        new_packet.append (decompressed_checksum_str);
    }
    else
    {
        new_packet.push_back ('0');
        new_packet.push_back ('0');
    }

    m_bytes.replace (0, size_of_first_packet, new_packet.data(), new_packet.size());

    free (decompressed_buffer);
    return true;
}

GDBRemoteCommunication::PacketType
GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
{
    // Put the packet data into the buffer in a thread safe fashion
    Mutex::Locker locker(m_bytes_mutex);
    
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));

    if (src && src_len > 0)
    {
        if (log && log->GetVerbose())
        {
            StreamString s;
            log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
                         __FUNCTION__, 
                         (uint32_t)src_len, 
                         (uint32_t)src_len, 
                         src);
        }
        m_bytes.append ((const char *)src, src_len);
    }

    bool isNotifyPacket = false;

    // Parse up the packets into gdb remote packets
    if (!m_bytes.empty())
    {
        // end_idx must be one past the last valid packet byte. Start
        // it off with an invalid value that is the same as the current
        // index.
        size_t content_start = 0;
        size_t content_length = 0;
        size_t total_length = 0;
        size_t checksum_idx = std::string::npos;

        // Size of packet before it is decompressed, for logging purposes
        size_t original_packet_size = m_bytes.size();
        if (CompressionIsEnabled())
        {
            if (DecompressPacket() == false)
            {
                packet.Clear();
                return GDBRemoteCommunication::PacketType::Standard;
            }
        }

        switch (m_bytes[0])
        {
            case '+':       // Look for ack
            case '-':       // Look for cancel
            case '\x03':    // ^C to halt target
                content_length = total_length = 1;  // The command is one byte long...
                break;

            case '%': // Async notify packet
                isNotifyPacket = true;
                // Intentional fall through

            case '$':
                // Look for a standard gdb packet?
                {
                    size_t hash_pos = m_bytes.find('#');
                    if (hash_pos != std::string::npos)
                    {
                        if (hash_pos + 2 < m_bytes.size())
                        {
                            checksum_idx = hash_pos + 1;
                            // Skip the dollar sign
                            content_start = 1; 
                            // Don't include the # in the content or the $ in the content length
                            content_length = hash_pos - 1;  
                            
                            total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
                        }
                        else
                        {
                            // Checksum bytes aren't all here yet
                            content_length = std::string::npos;
                        }
                    }
                }
                break;

            default:
                {
                    // We have an unexpected byte and we need to flush all bad 
                    // data that is in m_bytes, so we need to find the first
                    // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
                    // or '$' character (start of packet header) or of course,
                    // the end of the data in m_bytes...
                    const size_t bytes_len = m_bytes.size();
                    bool done = false;
                    uint32_t idx;
                    for (idx = 1; !done && idx < bytes_len; ++idx)
                    {
                        switch (m_bytes[idx])
                        {
                        case '+':
                        case '-':
                        case '\x03':
                        case '%':
                        case '$':
                            done = true;
                            break;
                                
                        default:
                            break;
                        }
                    }
                    if (log)
                        log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
                                     __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
                    m_bytes.erase(0, idx - 1);
                }
                break;
        }

        if (content_length == std::string::npos)
        {
            packet.Clear();
            return GDBRemoteCommunication::PacketType::Invalid;
        }
        else if (total_length > 0)
        {

            // We have a valid packet...
            assert (content_length <= m_bytes.size());
            assert (total_length <= m_bytes.size());
            assert (content_length <= total_length);
            size_t content_end = content_start + content_length;

            bool success = true;
            std::string &packet_str = packet.GetStringRef();
            if (log)
            {
                // If logging was just enabled and we have history, then dump out what
                // we have to the log so we get the historical context. The Dump() call that
                // logs all of the packet will set a boolean so that we don't dump this more
                // than once
                if (!m_history.DidDumpToLog ())
                    m_history.Dump (log);
                
                bool binary = false;
                // Only detect binary for packets that start with a '$' and have a '#CC' checksum
                if (m_bytes[0] == '$' && total_length > 4)
                {
                    for (size_t i=0; !binary && i<total_length; ++i)
                    {
                        if (isprint (m_bytes[i]) == 0 && isspace (m_bytes[i]) == 0)
                        {
                            binary = true;
                        }
                    }
                }
                if (binary)
                {
                    StreamString strm;
                    // Packet header...
                    if (CompressionIsEnabled())
                        strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c", (uint64_t) original_packet_size, (uint64_t)total_length, m_bytes[0]);
                    else
                        strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
                    for (size_t i=content_start; i<content_end; ++i)
                    {
                        // Remove binary escaped bytes when displaying the packet...
                        const char ch = m_bytes[i];
                        if (ch == 0x7d)
                        {
                            // 0x7d is the escape character.  The next character is to
                            // be XOR'd with 0x20.
                            const char escapee = m_bytes[++i] ^ 0x20;
                            strm.Printf("%2.2x", escapee);
                        }
                        else
                        {
                            strm.Printf("%2.2x", (uint8_t)ch);
                        }
                    }
                    // Packet footer...
                    strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
                    log->PutCString(strm.GetString().c_str());
                }
                else
                {
                    if (CompressionIsEnabled())
                        log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", (uint64_t) original_packet_size, (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
                    else
                        log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
                }
            }

            m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);

            // Clear packet_str in case there is some existing data in it.
            packet_str.clear();
            // Copy the packet from m_bytes to packet_str expanding the
            // run-length encoding in the process.
            // Reserve enough byte for the most common case (no RLE used)
            packet_str.reserve(m_bytes.length());
            for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
            {
                if (*c == '*')
                {
                    // '*' indicates RLE. Next character will give us the
                    // repeat count and previous character is what is to be
                    // repeated.
                    char char_to_repeat = packet_str.back();
                    // Number of time the previous character is repeated
                    int repeat_count = *++c + 3 - ' ';
                    // We have the char_to_repeat and repeat_count. Now push
                    // it in the packet.
                    for (int i = 0; i < repeat_count; ++i)
                        packet_str.push_back(char_to_repeat);
                }
                else if (*c == 0x7d)
                {
                    // 0x7d is the escape character.  The next character is to
                    // be XOR'd with 0x20.
                    char escapee = *++c ^ 0x20;
                    packet_str.push_back(escapee);
                }
                else
                {
                    packet_str.push_back(*c);
                }
            }

            if (m_bytes[0] == '$' || m_bytes[0] == '%')
            {
                assert (checksum_idx < m_bytes.size());
                if (::isxdigit (m_bytes[checksum_idx+0]) || 
                    ::isxdigit (m_bytes[checksum_idx+1]))
                {
                    if (GetSendAcks ())
                    {
                        const char *packet_checksum_cstr = &m_bytes[checksum_idx];
                        char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
                        char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
                        success = packet_checksum == actual_checksum;
                        if (!success)
                        {
                            if (log)
                                log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 
                                             (int)(total_length), 
                                             m_bytes.c_str(),
                                             (uint8_t)packet_checksum,
                                             (uint8_t)actual_checksum);
                        }
                        // Send the ack or nack if needed
                        if (!success)
                            SendNack();
                        else
                            SendAck();
                    }
                }
                else
                {
                    success = false;
                    if (log)
                        log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
                }
            }
            
            m_bytes.erase(0, total_length);
            packet.SetFilePos(0);

            if (isNotifyPacket)
                return GDBRemoteCommunication::PacketType::Notify;
            else
                return GDBRemoteCommunication::PacketType::Standard;
        }
    }
    packet.Clear();
    return GDBRemoteCommunication::PacketType::Invalid;
}

Error
GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
{
    Error error;
    if (m_listen_thread.IsJoinable())
    {
        error.SetErrorString("listen thread already running");
    }
    else
    {
        char listen_url[512];
        if (hostname && hostname[0])
            snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
        else
            snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
        m_listen_url = listen_url;
        SetConnection(new ConnectionFileDescriptor());
        m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error);
    }
    return error;
}

bool
GDBRemoteCommunication::JoinListenThread ()
{
    if (m_listen_thread.IsJoinable())
        m_listen_thread.Join(nullptr);
    return true;
}

lldb::thread_result_t
GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
{
    GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
    Error error;
    ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
    
    if (connection)
    {
        // Do the listen on another thread so we can continue on...
        if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
            comm->SetConnection(NULL);
    }
    return NULL;
}

Error
GDBRemoteCommunication::StartDebugserverProcess (const char *url,
                                                 Platform *platform,
                                                 ProcessLaunchInfo &launch_info,
                                                 uint16_t *port,
                                                 const Args& inferior_args)
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
    if (log)
        log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16, __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));

    Error error;
    // If we locate debugserver, keep that located version around
    static FileSpec g_debugserver_file_spec;
    
    char debugserver_path[PATH_MAX];
    FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
    
    // Always check to see if we have an environment override for the path
    // to the debugserver to use and use it if we do.
    const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
    if (env_debugserver_path)
    {
        debugserver_file_spec.SetFile (env_debugserver_path, false);
        if (log)
            log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
    }
    else
        debugserver_file_spec = g_debugserver_file_spec;
    bool debugserver_exists = debugserver_file_spec.Exists();
    if (!debugserver_exists)
    {
        // The debugserver binary is in the LLDB.framework/Resources
        // directory.
        if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec))
        {
            debugserver_file_spec.AppendPathComponent (DEBUGSERVER_BASENAME);
            debugserver_exists = debugserver_file_spec.Exists();
            if (debugserver_exists)
            {
                if (log)
                    log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());

                g_debugserver_file_spec = debugserver_file_spec;
            }
            else
            {
                debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
                if (debugserver_file_spec)
                {
                    // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
                    debugserver_exists = true;
                }
                else
                {
                    if (log)
                        log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
                }
                // Don't cache the platform specific GDB server binary as it could change
                // from platform to platform
                g_debugserver_file_spec.Clear();
            }
        }
    }
    
    if (debugserver_exists)
    {
        debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));

        Args &debugserver_args = launch_info.GetArguments();
        debugserver_args.Clear();
        char arg_cstr[PATH_MAX];

        // Start args with "debugserver /file/path -r --"
        debugserver_args.AppendArgument(debugserver_path);

#if !defined(__APPLE__)
        // First argument to lldb-server must be mode in which to run.
        debugserver_args.AppendArgument("gdbserver");
#endif

        // If a url is supplied then use it
        if (url)
            debugserver_args.AppendArgument(url);

        // use native registers, not the GDB registers
        debugserver_args.AppendArgument("--native-regs");

        if (launch_info.GetLaunchInSeparateProcessGroup())
        {
            debugserver_args.AppendArgument("--setsid");
        }

        llvm::SmallString<PATH_MAX> named_pipe_path;
        // socket_pipe is used by debug server to communicate back either
        // TCP port or domain socket name which it listens on.
        // The second purpose of the pipe to serve as a synchronization point -
        // once data is written to the pipe, debug server is up and running.
        Pipe socket_pipe;

        // port is null when debug server should listen on domain socket -
        // we're not interested in port value but rather waiting for debug server
        // to become available.
        if ((port != nullptr && *port == 0) || port == nullptr)
        {
            if (url)
            {
                // Create a temporary file to get the stdout/stderr and redirect the
                // output of the command into this file. We will later read this file
                // if all goes well and fill the data into "command_output_ptr"
    
#if defined(__APPLE__)
                // Binding to port zero, we need to figure out what port it ends up
                // using using a named pipe...
                error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
                if (error.Fail())
                {
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                "named pipe creation failed: %s",
                                __FUNCTION__, error.AsCString());
                    return error;
                }
                debugserver_args.AppendArgument("--named-pipe");
                debugserver_args.AppendArgument(named_pipe_path.c_str());
#else
                // Binding to port zero, we need to figure out what port it ends up
                // using using an unnamed pipe...
                error = socket_pipe.CreateNew(true);
                if (error.Fail())
                {
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                "unnamed pipe creation failed: %s",
                                __FUNCTION__, error.AsCString());
                    return error;
                }
                int write_fd = socket_pipe.GetWriteFileDescriptor();
                debugserver_args.AppendArgument("--pipe");
                debugserver_args.AppendArgument(std::to_string(write_fd).c_str());
                launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
#endif
            }
            else
            {
                // No host and port given, so lets listen on our end and make the debugserver
                // connect to us..
                error = StartListenThread ("127.0.0.1", 0);
                if (error.Fail())
                {
                    if (log)
                        log->Printf ("GDBRemoteCommunication::%s() unable to start listen thread: %s", __FUNCTION__, error.AsCString());
                    return error;
                }
    
                ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
                // Wait for 10 seconds to resolve the bound port
                *port = connection->GetListeningPort(10);
                if (*port > 0)
                {
                    char port_cstr[32];
                    snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", *port);
                    // Send the host and port down that debugserver and specify an option
                    // so that it connects back to the port we are listening to in this process
                    debugserver_args.AppendArgument("--reverse-connect");
                    debugserver_args.AppendArgument(port_cstr);
                }
                else
                {
                    error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
                    if (log)
                        log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
                    return error;
                }
            }
        }
        
        const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
        if (env_debugserver_log_file)
        {
            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
            debugserver_args.AppendArgument(arg_cstr);
        }
        
#if defined(__APPLE__)
        const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
        if (env_debugserver_log_flags)
        {
            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
            debugserver_args.AppendArgument(arg_cstr);
        }
#else
        const char *env_debugserver_log_channels = getenv("LLDB_SERVER_LOG_CHANNELS");
        if (env_debugserver_log_channels)
        {
            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-channels=%s", env_debugserver_log_channels);
            debugserver_args.AppendArgument(arg_cstr);
        }
#endif

        // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an env var doesn't come back.
        uint32_t env_var_index = 1;
        bool has_env_var;
        do
        {
            char env_var_name[64];
            snprintf (env_var_name, sizeof (env_var_name), "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
            const char *extra_arg = getenv(env_var_name);
            has_env_var = extra_arg != nullptr;

            if (has_env_var)
            {
                debugserver_args.AppendArgument (extra_arg);
                if (log)
                    log->Printf ("GDBRemoteCommunication::%s adding env var %s contents to stub command line (%s)", __FUNCTION__, env_var_name, extra_arg);
            }
        } while (has_env_var);

        if (inferior_args.GetArgumentCount() > 0)
        {
            debugserver_args.AppendArgument ("--");
            debugserver_args.AppendArguments (inferior_args);
        }

        // Copy the current environment to the gdbserver/debugserver instance
        StringList env;
        if (Host::GetEnvironment(env))
        {
            for (size_t i = 0; i < env.GetSize(); ++i)
                launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
        }

        // Close STDIN, STDOUT and STDERR.
        launch_info.AppendCloseFileAction (STDIN_FILENO);
        launch_info.AppendCloseFileAction (STDOUT_FILENO);
        launch_info.AppendCloseFileAction (STDERR_FILENO);

        // Redirect STDIN, STDOUT and STDERR to "/dev/null".
        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
        launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
        launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
        
        error = Host::LaunchProcess(launch_info);
        
        if (error.Success() &&
            launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
        {
            if (named_pipe_path.size() > 0)
            {
                error = socket_pipe.OpenAsReader(named_pipe_path, false);
                if (error.Fail())
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                "failed to open named pipe %s for reading: %s",
                                __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
            }

            if (socket_pipe.CanWrite())
                socket_pipe.CloseWriteFileDescriptor();
            if (socket_pipe.CanRead())
            {
                char port_cstr[PATH_MAX] = {0};
                port_cstr[0] = '\0';
                size_t num_bytes = sizeof(port_cstr);
                // Read port from pipe with 10 second timeout.
                error = socket_pipe.ReadWithTimeout(port_cstr, num_bytes,
                        std::chrono::seconds{10}, num_bytes);
                if (error.Success() && (port != nullptr))
                {
                    assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
                    *port = StringConvert::ToUInt32(port_cstr, 0);
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                    "debugserver listens %u port",
                                    __FUNCTION__, *port);
                }
                else
                {
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                "failed to read a port value from pipe %s: %s",
                                __FUNCTION__, named_pipe_path.c_str(), error.AsCString());

                }
                socket_pipe.Close();
            }

            if (named_pipe_path.size() > 0)
            {
                const auto err = socket_pipe.Delete(named_pipe_path);
                if (err.Fail())
                {
                    if (log)
                        log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s",
                                __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
                }
            }

            // Make sure we actually connect with the debugserver...
            JoinListenThread();
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
    }

    if (error.Fail())
    {
        if (log)
            log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
    }

    return error;
}

void
GDBRemoteCommunication::DumpHistory(Stream &strm)
{
    m_history.Dump (strm);
}

GDBRemoteCommunication::ScopedTimeout::ScopedTimeout (GDBRemoteCommunication& gdb_comm,
                                                      uint32_t timeout) :
    m_gdb_comm (gdb_comm)
{
    m_saved_timeout = m_gdb_comm.SetPacketTimeout (timeout);
}

GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout ()
{
    m_gdb_comm.SetPacketTimeout (m_saved_timeout);
}

// This function is called via the Communications class read thread when bytes become available
// for this connection. This function will consume all incoming bytes and try to parse whole
// packets as they become available. Full packets are placed in a queue, so that all packet
// requests can simply pop from this queue. Async notification packets will be dispatched
// immediately to the ProcessGDBRemote Async thread via an event.
void GDBRemoteCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status)
{
    StringExtractorGDBRemote packet;

    while (true)
    {
        PacketType type = CheckForPacket(bytes, len, packet);

        // scrub the data so we do not pass it back to CheckForPacket
        // on future passes of the loop
        bytes = nullptr;
        len = 0;

        // we may have received no packet so lets bail out
        if (type == PacketType::Invalid)
            break;

        if (type == PacketType::Standard)
        {
            // scope for the mutex
            {
                // lock down the packet queue
                Mutex::Locker locker(m_packet_queue_mutex);
                // push a new packet into the queue
                m_packet_queue.push(packet);
                // Signal condition variable that we have a packet
                m_condition_queue_not_empty.Signal();

            }
        }

        if (type == PacketType::Notify)
        {
            // put this packet into an event
            const char *pdata = packet.GetStringRef().c_str();

            // as the communication class, we are a broadcaster and the
            // async thread is tuned to listen to us
            BroadcastEvent(
                eBroadcastBitGdbReadThreadGotNotify,
                new EventDataBytes(pdata));
        }
    }
}
