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

// C Includes
#include <errno.h>
#include <spawn.h>
#include <sys/types.h>
#include <sys/stat.h>

// C++ Includes
#include <algorithm>
#include <map>

// Other libraries and framework includes

#include "lldb/Breakpoint/WatchpointLocation.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/FileSpec.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/PseudoTerminal.h"

// Project includes
#include "lldb/Host/Host.h"
#include "Utility/StringExtractorGDBRemote.h"
#include "GDBRemoteRegisterContext.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
#include "MacOSXLibunwindCallbacks.h"
#include "StopInfoMachException.h"



#define DEBUGSERVER_BASENAME    "debugserver"
using namespace lldb;
using namespace lldb_private;

static inline uint16_t
get_random_port ()
{
    return (arc4random() % (UINT16_MAX - 1000u)) + 1000u;
}


const char *
ProcessGDBRemote::GetPluginNameStatic()
{
    return "process.gdb-remote";
}

const char *
ProcessGDBRemote::GetPluginDescriptionStatic()
{
    return "GDB Remote protocol based debugging plug-in.";
}

void
ProcessGDBRemote::Terminate()
{
    PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
}


Process*
ProcessGDBRemote::CreateInstance (Target &target, Listener &listener)
{
    return new ProcessGDBRemote (target, listener);
}

bool
ProcessGDBRemote::CanDebug(Target &target)
{
    // For now we are just making sure the file exists for a given module
    ModuleSP exe_module_sp(target.GetExecutableModule());
    if (exe_module_sp.get())
        return exe_module_sp->GetFileSpec().Exists();
    // However, if there is no executable module, we return true since we might be preparing to attach.
    return true;
}

//----------------------------------------------------------------------
// ProcessGDBRemote constructor
//----------------------------------------------------------------------
ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
    Process (target, listener),
    m_dynamic_loader_ap (),
    m_flags (0),
    m_stdio_communication ("gdb-remote.stdio"),
    m_stdio_mutex (Mutex::eMutexTypeRecursive),
    m_stdout_data (),
    m_byte_order (eByteOrderHost),
    m_gdb_comm(),
    m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
    m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
    m_last_stop_packet (),
    m_register_info (),
    m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
    m_async_thread (LLDB_INVALID_HOST_THREAD),
    m_curr_tid (LLDB_INVALID_THREAD_ID),
    m_curr_tid_run (LLDB_INVALID_THREAD_ID),
    m_z0_supported (1),
    m_continue_packet(),
    m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
    m_packet_timeout (1),
    m_max_memory_size (512),
    m_libunwind_target_type (UNW_TARGET_UNSPECIFIED),
    m_libunwind_addr_space (NULL),
    m_waiting_for_attach (false),
    m_local_debugserver (true)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ProcessGDBRemote::~ProcessGDBRemote()
{
    if (m_debugserver_thread != LLDB_INVALID_HOST_THREAD)
    {
        Host::ThreadCancel (m_debugserver_thread, NULL);
        thread_result_t thread_result;
        Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
        m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
    }
    //  m_mach_process.UnregisterNotificationCallbacks (this);
    Clear();
}

//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
const char *
ProcessGDBRemote::GetPluginName()
{
    return "Process debugging plug-in that uses the GDB remote protocol";
}

const char *
ProcessGDBRemote::GetShortPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
ProcessGDBRemote::GetPluginVersion()
{
    return 1;
}

void
ProcessGDBRemote::GetPluginCommandHelp (const char *command, Stream *strm)
{
    strm->Printf("TODO: fill this in\n");
}

Error
ProcessGDBRemote::ExecutePluginCommand (Args &command, Stream *strm)
{
    Error error;
    error.SetErrorString("No plug-in commands are currently supported.");
    return error;
}

Log *
ProcessGDBRemote::EnablePluginLogging (Stream *strm, Args &command)
{
    return NULL;
}

void
ProcessGDBRemote::BuildDynamicRegisterInfo ()
{
    char register_info_command[64];
    m_register_info.Clear();
    StringExtractorGDBRemote::Type packet_type = StringExtractorGDBRemote::eResponse;
    uint32_t reg_offset = 0;
    uint32_t reg_num = 0;
    for (; packet_type == StringExtractorGDBRemote::eResponse; ++reg_num)
    {
        ::snprintf (register_info_command, sizeof(register_info_command), "qRegisterInfo%x", reg_num);
        StringExtractorGDBRemote response;
        if (m_gdb_comm.SendPacketAndWaitForResponse(register_info_command, response, 2, false))
        {
            packet_type = response.GetType();
            if (packet_type == StringExtractorGDBRemote::eResponse)
            {
                std::string name;
                std::string value;
                ConstString reg_name;
                ConstString alt_name;
                ConstString set_name;
                RegisterInfo reg_info = { NULL,                 // Name
                    NULL,                 // Alt name
                    0,                    // byte size
                    reg_offset,           // offset
                    eEncodingUint,        // encoding
                    eFormatHex,           // formate
                    {
                        LLDB_INVALID_REGNUM, // GCC reg num
                        LLDB_INVALID_REGNUM, // DWARF reg num
                        LLDB_INVALID_REGNUM, // generic reg num
                        reg_num,             // GDB reg num
                        reg_num           // native register number
                    }
                };

                while (response.GetNameColonValue(name, value))
                {
                    if (name.compare("name") == 0)
                    {
                        reg_name.SetCString(value.c_str());
                    }
                    else if (name.compare("alt-name") == 0)
                    {
                        alt_name.SetCString(value.c_str());
                    }
                    else if (name.compare("bitsize") == 0)
                    {
                        reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
                    }
                    else if (name.compare("offset") == 0)
                    {
                        uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
                        if (reg_offset != offset)
                        {
                            reg_offset = offset;
                        }
                    }
                    else if (name.compare("encoding") == 0)
                    {
                        if (value.compare("uint") == 0)
                            reg_info.encoding = eEncodingUint;
                        else if (value.compare("sint") == 0)
                            reg_info.encoding = eEncodingSint;
                        else if (value.compare("ieee754") == 0)
                            reg_info.encoding = eEncodingIEEE754;
                        else if (value.compare("vector") == 0)
                            reg_info.encoding = eEncodingVector;
                    }
                    else if (name.compare("format") == 0)
                    {
                        if (value.compare("binary") == 0)
                            reg_info.format = eFormatBinary;
                        else if (value.compare("decimal") == 0)
                            reg_info.format = eFormatDecimal;
                        else if (value.compare("hex") == 0)
                            reg_info.format = eFormatHex;
                        else if (value.compare("float") == 0)
                            reg_info.format = eFormatFloat;
                        else if (value.compare("vector-sint8") == 0)
                            reg_info.format = eFormatVectorOfSInt8;
                        else if (value.compare("vector-uint8") == 0)
                            reg_info.format = eFormatVectorOfUInt8;
                        else if (value.compare("vector-sint16") == 0)
                            reg_info.format = eFormatVectorOfSInt16;
                        else if (value.compare("vector-uint16") == 0)
                            reg_info.format = eFormatVectorOfUInt16;
                        else if (value.compare("vector-sint32") == 0)
                            reg_info.format = eFormatVectorOfSInt32;
                        else if (value.compare("vector-uint32") == 0)
                            reg_info.format = eFormatVectorOfUInt32;
                        else if (value.compare("vector-float32") == 0)
                            reg_info.format = eFormatVectorOfFloat32;
                        else if (value.compare("vector-uint128") == 0)
                            reg_info.format = eFormatVectorOfUInt128;
                    }
                    else if (name.compare("set") == 0)
                    {
                        set_name.SetCString(value.c_str());
                    }
                    else if (name.compare("gcc") == 0)
                    {
                        reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
                    }
                    else if (name.compare("dwarf") == 0)
                    {
                        reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
                    }
                    else if (name.compare("generic") == 0)
                    {
                        if (value.compare("pc") == 0)
                            reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
                        else if (value.compare("sp") == 0)
                            reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
                        else if (value.compare("fp") == 0)
                            reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
                        else if (value.compare("ra") == 0)
                            reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
                        else if (value.compare("flags") == 0)
                            reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
                    }
                }

                reg_info.byte_offset = reg_offset;
                assert (reg_info.byte_size != 0);
                reg_offset += reg_info.byte_size;
                m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
            }
        }
        else
        {
            packet_type = StringExtractorGDBRemote::eError;
        }
    }

    if (reg_num == 0)
    {
        // We didn't get anything. See if we are debugging ARM and fill with
        // a hard coded register set until we can get an updated debugserver
        // down on the devices.
        ArchSpec arm_arch ("arm");
        if (GetTarget().GetArchitecture() == arm_arch)
            m_register_info.HardcodeARMRegisters();
    }
    m_register_info.Finalize ();
}

Error
ProcessGDBRemote::WillLaunch (Module* module)
{
    return WillLaunchOrAttach ();
}

Error
ProcessGDBRemote::WillAttach (lldb::pid_t pid)
{
    return WillLaunchOrAttach ();
}

Error
ProcessGDBRemote::WillAttach (const char *process_name, bool wait_for_launch)
{
    return WillLaunchOrAttach ();
}

Error
ProcessGDBRemote::WillLaunchOrAttach ()
{
    Error error;
    // TODO: this is hardcoded for macosx right now. We need this to be more dynamic
    m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld"));

    if (m_dynamic_loader_ap.get() == NULL)
        error.SetErrorString("unable to find the dynamic loader named 'dynamic-loader.macosx-dyld'");
    m_stdio_communication.Clear ();
    
    return error;
}

//#define LAUNCH_WITH_LAUNCH_SERVICES 1
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
Error
ProcessGDBRemote::DoLaunch
(
    Module* module,
    char const *argv[],
    char const *envp[],
    uint32_t launch_flags,
    const char *stdin_path,
    const char *stdout_path,
    const char *stderr_path
)
{
    Error error;
#if defined (LAUNCH_WITH_LAUNCH_SERVICES)
    FileSpec app_file_spec (argv[0]);
    pid_t pid = Host::LaunchApplication (app_file_spec);
    if (pid != LLDB_INVALID_PROCESS_ID)
        error = DoAttachToProcessWithID (pid);
    else
        error.SetErrorString("failed");
#else
    //  ::LogSetBitMask (GDBR_LOG_DEFAULT);
    //  ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
    //  ::LogSetLogFile ("/dev/stdout");

    ObjectFile * object_file = module->GetObjectFile();
    if (object_file)
    {
        ArchSpec inferior_arch(module->GetArchitecture());
        char host_port[128];
        snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());

        bool start_debugserver_with_inferior_args = false;
        if (start_debugserver_with_inferior_args)
        {
            // We want to launch debugserver with the inferior program and its
            // arguments on the command line. We should only do this if we
            // the GDB server we are talking to doesn't support the 'A' packet.
            error = StartDebugserverProcess (host_port,
                                             argv,
                                             envp,
                                             NULL, //stdin_path,
                                             LLDB_INVALID_PROCESS_ID,
                                             NULL, false,
                                             (launch_flags & eLaunchFlagDisableASLR) != 0,
                                             inferior_arch);
            if (error.Fail())
                return error;

            error = ConnectToDebugserver (host_port);
            if (error.Success())
            {
                SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout));
            }
        }
        else
        {
            error = StartDebugserverProcess (host_port,
                                             NULL,
                                             NULL,
                                             NULL, //stdin_path,
                                             LLDB_INVALID_PROCESS_ID,
                                             NULL, false,
                                             (launch_flags & eLaunchFlagDisableASLR) != 0,
                                             inferior_arch);
            if (error.Fail())
                return error;

            error = ConnectToDebugserver (host_port);
            if (error.Success())
            {
                // Send the environment and the program + arguments after we connect
                if (envp)
                {
                    const char *env_entry;
                    for (int i=0; (env_entry = envp[i]); ++i)
                    {
                        if (m_gdb_comm.SendEnvironmentPacket(env_entry, m_packet_timeout) != 0)
                            break;
                    }
                }

				// FIXME: convert this to use the new set/show variables when they are available
#if 0
                if (::getenv ("LLDB_DEBUG_DEBUGSERVER"))
                {
                    const uint32_t attach_debugserver_secs = 10;
                    ::printf ("attach to debugserver (pid = %i)\n", m_debugserver_pid);
                    for (uint32_t i=0; i<attach_debugserver_secs; ++i)
                    {
                        printf ("%i\n", attach_debugserver_secs - i);
                        sleep (1);
                    }
                }
#endif

                const uint32_t arg_timeout_seconds = 10;
                int arg_packet_err = m_gdb_comm.SendArgumentsPacket (argv, arg_timeout_seconds);
                if (arg_packet_err == 0)
                {
                    std::string error_str;
                    if (m_gdb_comm.GetLaunchSuccess (m_packet_timeout, error_str))
                    {
                        SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout));
                    }
                    else
                    {
                        error.SetErrorString (error_str.c_str());
                    }
                }
                else
                {
                    error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err);
                }
                
                SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout));
            }
        }

        if (GetID() == LLDB_INVALID_PROCESS_ID)
        {
            KillDebugserverProcess ();
            return error;
        }
    
        StringExtractorGDBRemote response;
        if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, m_packet_timeout, false))
            SetPrivateState (SetThreadStopInfo (response));

    }
    else
    {
        // Set our user ID to an invalid process ID.
        SetID(LLDB_INVALID_PROCESS_ID);
        error.SetErrorStringWithFormat("Failed to get object file from '%s' for arch %s.\n", module->GetFileSpec().GetFilename().AsCString(), module->GetArchitecture().AsCString());
    }
#endif
    return error;

}


Error
ProcessGDBRemote::ConnectToDebugserver (const char *host_port)
{
    Error error;
    // Sleep and wait a bit for debugserver to start to listen...
    std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
    if (conn_ap.get())
    {
        std::string connect_url("connect://");
        connect_url.append (host_port);
        const uint32_t max_retry_count = 50;
        uint32_t retry_count = 0;
        while (!m_gdb_comm.IsConnected())
        {
            if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
            {
                m_gdb_comm.SetConnection (conn_ap.release());
                break;
            }
            retry_count++;

            if (retry_count >= max_retry_count)
                break;

            usleep (100000);
        }
    }

    if (!m_gdb_comm.IsConnected())
    {
        if (error.Success())
            error.SetErrorString("not connected to remote gdb server");
        return error;
    }

    m_gdb_comm.SetAckMode (true);
    if (m_gdb_comm.StartReadThread(&error))
    {
        // Send an initial ack
        m_gdb_comm.SendAck('+');

        if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
            m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
                                                                      this,
                                                                      m_debugserver_pid,
                                                                      false);
        
        StringExtractorGDBRemote response;
        if (m_gdb_comm.SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
        {
            if (response.IsOKPacket())
                m_gdb_comm.SetAckMode (false);
        }

        BuildDynamicRegisterInfo ();
    }
    return error;
}

void
ProcessGDBRemote::DidLaunchOrAttach ()
{
    ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::DidLaunch()");
    if (GetID() == LLDB_INVALID_PROCESS_ID)
    {
        m_dynamic_loader_ap.reset();
    }
    else
    {
        m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;

        Module * exe_module = GetTarget().GetExecutableModule ().get();        
        assert(exe_module);

        ObjectFile *exe_objfile = exe_module->GetObjectFile();
        assert(exe_objfile);

        m_byte_order = exe_objfile->GetByteOrder();
        assert (m_byte_order != eByteOrderInvalid);

        StreamString strm;

        ArchSpec inferior_arch;
        // See if the GDB server supports the qHostInfo information
        const char *vendor = m_gdb_comm.GetVendorString().AsCString();
        const char *os_type = m_gdb_comm.GetOSString().AsCString();
        ArchSpec arch_spec = GetTarget().GetArchitecture();
        
        if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm"))
        {
            // For ARM we can't trust the arch of the process as it could
            // have an armv6 object file, but be running on armv7 kernel.
            inferior_arch = m_gdb_comm.GetHostArchitecture();
        }
        
        if (!inferior_arch.IsValid())
            inferior_arch = arch_spec;

        if (vendor == NULL)
            vendor = Host::GetVendorString().AsCString("apple");
        
        if (os_type == NULL)
            os_type = Host::GetOSString().AsCString("darwin");

        strm.Printf ("%s-%s-%s", inferior_arch.AsCString(), vendor, os_type);

        std::transform (strm.GetString().begin(), 
                        strm.GetString().end(), 
                        strm.GetString().begin(), 
                        ::tolower);

        m_target_triple.SetCString(strm.GetString().c_str());
    }
}

void
ProcessGDBRemote::DidLaunch ()
{
#if defined (LAUNCH_WITH_LAUNCH_SERVICES)
    DidAttach ();
#else
    DidLaunchOrAttach ();
    if (m_dynamic_loader_ap.get())
        m_dynamic_loader_ap->DidLaunch();
#endif
}

Error
ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
{
    Error error;
    // Clear out and clean up from any current state
    Clear();
    ArchSpec arch_spec = GetTarget().GetArchitecture();
    
    //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
    
    
    if (attach_pid != LLDB_INVALID_PROCESS_ID)
    {
        SetPrivateState (eStateAttaching);
        char host_port[128];
        snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
        error = StartDebugserverProcess (host_port,                 // debugserver_url
                                         NULL,                      // inferior_argv
                                         NULL,                      // inferior_envp
                                         NULL,                      // stdin_path
                                         LLDB_INVALID_PROCESS_ID,   // attach_pid
                                         NULL,                      // attach_pid_name
                                         false,                     // wait_for_launch
                                         false,                     // disable_aslr
                                         arch_spec);
        
        if (error.Fail())
        {
            const char *error_string = error.AsCString();
            if (error_string == NULL)
                error_string = "unable to launch " DEBUGSERVER_BASENAME;

            SetExitStatus (-1, error_string);
        }
        else
        {
            error = ConnectToDebugserver (host_port);
            if (error.Success())
            {
                char packet[64];
                const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", attach_pid);
                StringExtractorGDBRemote response;
                StateType stop_state = m_gdb_comm.SendContinuePacketAndWaitForResponse (this, 
                                                                                        packet, 
                                                                                        packet_len, 
                                                                                        response);
                switch (stop_state)
                {
                case eStateStopped:
                case eStateCrashed:
                case eStateSuspended:
                    SetID (attach_pid);
                    m_last_stop_packet = response;
                    m_last_stop_packet.SetFilePos (0);
                    SetPrivateState (stop_state);
                    break;

                case eStateExited:
                    m_last_stop_packet = response;
                    m_last_stop_packet.SetFilePos (0);
                    response.SetFilePos(1);
                    SetExitStatus(response.GetHexU8(), NULL);
                    break;

                default:
                    SetExitStatus(-1, "unable to attach to process");
                    break;
                }

            }
        }
    }

    lldb::pid_t pid = GetID();
    if (pid == LLDB_INVALID_PROCESS_ID)
    {
        KillDebugserverProcess();
    }
    return error;
}

size_t
ProcessGDBRemote::AttachInputReaderCallback
(
    void *baton, 
    InputReader *reader, 
    lldb::InputReaderAction notification,
    const char *bytes, 
    size_t bytes_len
)
{
    if (notification == eInputReaderGotToken)
    {
        ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
        if (gdb_process->m_waiting_for_attach)
            gdb_process->m_waiting_for_attach = false;
        reader->SetIsDone(true);
        return 1;
    }
    return 0;
}

Error
ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
{
    Error error;
    // Clear out and clean up from any current state
    Clear();
    // HACK: require arch be set correctly at the target level until we can
    // figure out a good way to determine the arch of what we are attaching to

    //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
    if (process_name && process_name[0])
    {

        SetPrivateState (eStateAttaching);
        char host_port[128];
        ArchSpec arch_spec = GetTarget().GetArchitecture();
        snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
        error = StartDebugserverProcess (host_port,                 // debugserver_url
                                         NULL,                      // inferior_argv
                                         NULL,                      // inferior_envp
                                         NULL,                      // stdin_path
                                         LLDB_INVALID_PROCESS_ID,   // attach_pid
                                         NULL,                      // attach_pid_name
                                         false,                     // wait_for_launch
                                         false,                     // disable_aslr
                                         arch_spec);
        if (error.Fail())
        {
            const char *error_string = error.AsCString();
            if (error_string == NULL)
                error_string = "unable to launch " DEBUGSERVER_BASENAME;

            SetExitStatus (-1, error_string);
        }
        else
        {
            error = ConnectToDebugserver (host_port);
            if (error.Success())
            {
                StreamString packet;
                
                packet.PutCString("vAttach");
                if (wait_for_launch)
                    packet.PutCString("Wait");
                packet.PutChar(';');
                packet.PutBytesAsRawHex8(process_name, strlen(process_name), eByteOrderHost, eByteOrderHost);
                StringExtractorGDBRemote response;
                StateType stop_state = m_gdb_comm.SendContinuePacketAndWaitForResponse (this, 
                                                                                        packet.GetData(), 
                                                                                        packet.GetSize(), 
                                                                                        response);
                switch (stop_state)
                {
                case eStateStopped:
                case eStateCrashed:
                case eStateSuspended:
                    SetID (m_gdb_comm.GetCurrentProcessID(m_packet_timeout));
                    m_last_stop_packet = response;
                    m_last_stop_packet.SetFilePos (0);
                    SetPrivateState (stop_state);
                    break;

                case eStateExited:
                    m_last_stop_packet = response;
                    m_last_stop_packet.SetFilePos (0);
                    response.SetFilePos(1);
                    SetExitStatus(response.GetHexU8(), NULL);
                    break;

                default:
                    SetExitStatus(-1, "unable to attach to process");
                    break;
                }
            }
        }
    }

    lldb::pid_t pid = GetID();
    if (pid == LLDB_INVALID_PROCESS_ID)
    {
        KillDebugserverProcess();
    }
    return error;
}

//                              
//        if (wait_for_launch)
//        {
//            InputReaderSP reader_sp (new InputReader());
//            StreamString instructions;
//            instructions.Printf("Hit any key to cancel waiting for '%s' to launch...", process_name);
//            error = reader_sp->Initialize (AttachInputReaderCallback, // callback
//                                                this, // baton
//                                                eInputReaderGranularityByte,
//                                                NULL, // End token
//                                                false);
//            
//            StringExtractorGDBRemote response;
//            m_waiting_for_attach = true;
//            FILE *reader_out_fh = reader_sp->GetOutputFileHandle();
//            while (m_waiting_for_attach)
//            {
//                // Wait for one second for the stop reply packet
//                if (m_gdb_comm.WaitForPacket(response, 1))
//                {
//                    // Got some sort of packet, see if it is the stop reply packet?
//                    char ch = response.GetChar(0);
//                    if (ch == 'T')
//                    {
//                        m_waiting_for_attach = false;
//                    }
//                }
//                else
//                {
//                    // Put a period character every second
//                    fputc('.', reader_out_fh);
//                }
//            }
//        }
//    }
//    return GetID();
//}

void
ProcessGDBRemote::DidAttach ()
{
    // If we haven't got an executable module yet, then we should make a dynamic loader, and
    // see if it can find the executable module for us.  If we do have an executable module,
    // make sure it matches the process we've just attached to.
    
    ModuleSP exe_module_sp = GetTarget().GetExecutableModule();        
    if (!m_dynamic_loader_ap.get())
    {
       m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld"));
    }

    if (m_dynamic_loader_ap.get())
        m_dynamic_loader_ap->DidAttach();

    Module * new_exe_module = GetTarget().GetExecutableModule().get();        
    if (new_exe_module == NULL)
    {
        
    }
    
    DidLaunchOrAttach ();
}

Error
ProcessGDBRemote::WillResume ()
{
    m_continue_packet.Clear();
    // Start the continue packet we will use to run the target. Each thread
    // will append what it is supposed to be doing to this packet when the
    // ThreadList::WillResume() is called. If a thread it supposed
    // to stay stopped, then don't append anything to this string.
    m_continue_packet.Printf("vCont");
    return Error();
}

Error
ProcessGDBRemote::DoResume ()
{
    ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::Resume()");
    m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize()));
    return Error();
}

size_t
ProcessGDBRemote::GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site)
{
    const uint8_t *trap_opcode = NULL;
    uint32_t trap_opcode_size = 0;

    static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
    //static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
    static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
    static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };

    ArchSpec::CPU arch_cpu = GetTarget().GetArchitecture().GetGenericCPUType();
    switch (arch_cpu)
    {
    case ArchSpec::eCPU_i386:
    case ArchSpec::eCPU_x86_64:
        trap_opcode = g_i386_breakpoint_opcode;
        trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
        break;
    
    case ArchSpec::eCPU_arm:
        // TODO: fill this in for ARM. We need to dig up the symbol for
        // the address in the breakpoint locaiton and figure out if it is
        // an ARM or Thumb breakpoint.
        trap_opcode = g_arm_breakpoint_opcode;
        trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
        break;
    
    case ArchSpec::eCPU_ppc:
    case ArchSpec::eCPU_ppc64:
        trap_opcode = g_ppc_breakpoint_opcode;
        trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
        break;

    default:
        assert(!"Unhandled architecture in ProcessMacOSX::GetSoftwareBreakpointTrapOpcode()");
        break;
    }

    if (trap_opcode && trap_opcode_size)
    {
        if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
            return trap_opcode_size;
    }
    return 0;
}

uint32_t
ProcessGDBRemote::UpdateThreadListIfNeeded ()
{
    // locker will keep a mutex locked until it goes out of scope
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD);
    if (log && log->GetMask().IsSet(GDBR_LOG_VERBOSE))
        log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID());

    Mutex::Locker locker (m_thread_list.GetMutex ());
    const uint32_t stop_id = GetStopID();
    if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
    {
        // Update the thread list's stop id immediately so we don't recurse into this function.
        ThreadList curr_thread_list (this);
        curr_thread_list.SetStopID(stop_id);

        Error err;
        StringExtractorGDBRemote response;
        for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, 1, false);
             response.IsNormalPacket();
             m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, 1, false))
        {
            char ch = response.GetChar();
            if (ch == 'l')
                break;
            if (ch == 'm')
            {
                do
                {
                    tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);

                    if (tid != LLDB_INVALID_THREAD_ID)
                    {
                        ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
                        if (thread_sp)
                            thread_sp->GetRegisterContext()->Invalidate();
                        else
                            thread_sp.reset (new ThreadGDBRemote (*this, tid));
                        curr_thread_list.AddThread(thread_sp);
                    }

                    ch = response.GetChar();
                } while (ch == ',');
            }
        }

        m_thread_list = curr_thread_list;

        SetThreadStopInfo (m_last_stop_packet);
    }
    return GetThreadList().GetSize(false);
}


StateType
ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
{
    const char stop_type = stop_packet.GetChar();
    switch (stop_type)
    {
    case 'T':
    case 'S':
        {
            // Stop with signal and thread info
            const uint8_t signo = stop_packet.GetHexU8();
            std::string name;
            std::string value;
            std::string thread_name;
            uint32_t exc_type = 0;
            std::vector<addr_t> exc_data;
            uint32_t tid = LLDB_INVALID_THREAD_ID;
            addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
            uint32_t exc_data_count = 0;
            while (stop_packet.GetNameColonValue(name, value))
            {
                if (name.compare("metype") == 0)
                {
                    // exception type in big endian hex
                    exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
                }
                else if (name.compare("mecount") == 0)
                {
                    // exception count in big endian hex
                    exc_data_count = Args::StringToUInt32 (value.c_str(), 0, 16);
                }
                else if (name.compare("medata") == 0)
                {
                    // exception data in big endian hex
                    exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
                }
                else if (name.compare("thread") == 0)
                {
                    // thread in big endian hex
                    tid = Args::StringToUInt32 (value.c_str(), 0, 16);
                }
                else if (name.compare("name") == 0)
                {
                    thread_name.swap (value);
                }
                else if (name.compare("qaddr") == 0)
                {
                    thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
                }
            }
            ThreadSP thread_sp (m_thread_list.FindThreadByID(tid, false));

            if (thread_sp)
            {
                ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());

                gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
                gdb_thread->SetName (thread_name.empty() ? thread_name.c_str() : NULL);
                if (exc_type != 0)
                {
                    const size_t exc_data_count = exc_data.size();

                    gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
                                                                                                       exc_type, 
                                                                                                       exc_data_count,
                                                                                                       exc_data_count >= 1 ? exc_data[0] : 0,
                                                                                                       exc_data_count >= 2 ? exc_data[1] : 0));
                }
                else if (signo)
                {
                    gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
                }
                else
                {
                    StopInfoSP invalid_stop_info_sp;
                    gdb_thread->SetStopInfo (invalid_stop_info_sp);
                }
            }
            return eStateStopped;
        }
        break;

    case 'W':
        // process exited
        return eStateExited;

    default:
        break;
    }
    return eStateInvalid;
}

void
ProcessGDBRemote::RefreshStateAfterStop ()
{
    // FIXME - add a variable to tell that we're in the middle of attaching if we
    // need to know that.
    // We must be attaching if we don't already have a valid architecture
//    if (!GetTarget().GetArchitecture().IsValid())
//    {
//        Module *exe_module = GetTarget().GetExecutableModule().get();
//        if (exe_module)
//            m_arch_spec = exe_module->GetArchitecture();
//    }
    
    // Let all threads recover from stopping and do any clean up based
    // on the previous thread state (if any).
    m_thread_list.RefreshStateAfterStop();

    // Discover new threads:
    UpdateThreadListIfNeeded ();
}

Error
ProcessGDBRemote::DoHalt ()
{
    Error error;
    if (m_gdb_comm.IsRunning())
    {
        bool timed_out = false;
        Mutex::Locker locker;
        if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
        {
            if (timed_out)
                error.SetErrorString("timed out sending interrupt packet");
            else
                error.SetErrorString("unknown error sending interrupt packet");
        }
    }
    return error;
}

Error
ProcessGDBRemote::WillDetach ()
{
    Error error;

    if (m_gdb_comm.IsRunning())
    {
        bool timed_out = false;
        Mutex::Locker locker;
        if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
        {
            if (timed_out)
                error.SetErrorString("timed out sending interrupt packet");
            else
                error.SetErrorString("unknown error sending interrupt packet");
        }
    }
    return error;
}

Error
ProcessGDBRemote::DoDetach()
{
    Error error;
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
    if (log)
        log->Printf ("ProcessGDBRemote::DoDetach()");

    DisableAllBreakpointSites ();

    StringExtractorGDBRemote response;
    size_t response_size = m_gdb_comm.SendPacketAndWaitForResponse("D", response, 2, false);
    if (response_size)
    {
        if (response.IsOKPacket())
        {
            if (log)
                log->Printf ("ProcessGDBRemote::DoDetach() detach was successful");

        }
        else if (log)
        {
            log->Printf ("ProcessGDBRemote::DoDestroy() detach failed: %s", response.GetStringRef().c_str());
        }
    }
    else if (log)
    {
        log->PutCString ("ProcessGDBRemote::DoDestroy() detach failed for unknown reasons");
    }
    StopAsyncThread ();
    m_gdb_comm.StopReadThread();
    KillDebugserverProcess ();
    m_gdb_comm.Disconnect();    // Disconnect from the debug server.
    SetPublicState (eStateDetached);
    return error;
}

Error
ProcessGDBRemote::DoDestroy ()
{
    Error error;
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
    if (log)
        log->Printf ("ProcessGDBRemote::DoDestroy()");

    // Interrupt if our inferior is running...
    Mutex::Locker locker;
    m_gdb_comm.SendInterrupt (locker, 1);
    DisableAllBreakpointSites ();
    SetExitStatus(-1, "process killed");

    StringExtractorGDBRemote response;
    if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, 2, false))
    {
        if (log)
        {
            if (response.IsOKPacket())
                log->Printf ("ProcessGDBRemote::DoDestroy() kill was successful");
            else
                log->Printf ("ProcessGDBRemote::DoDestroy() kill failed: %s", response.GetStringRef().c_str());
        }
    }

    StopAsyncThread ();
    m_gdb_comm.StopReadThread();
    KillDebugserverProcess ();
    m_gdb_comm.Disconnect();    // Disconnect from the debug server.
    return error;
}

ByteOrder
ProcessGDBRemote::GetByteOrder () const
{
    return m_byte_order;
}

//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------

bool
ProcessGDBRemote::IsAlive ()
{
    return m_gdb_comm.IsConnected();
}

addr_t
ProcessGDBRemote::GetImageInfoAddress()
{
    if (!m_gdb_comm.IsRunning())
    {
        StringExtractorGDBRemote response;
        if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, 2, false))
        {
            if (response.IsNormalPacket())
                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
        }
    }
    return LLDB_INVALID_ADDRESS;
}

DynamicLoader *
ProcessGDBRemote::GetDynamicLoader()
{
    return m_dynamic_loader_ap.get();
}

//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
size_t
ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
    if (size > m_max_memory_size)
    {
        // Keep memory read sizes down to a sane limit. This function will be
        // called multiple times in order to complete the task by 
        // lldb_private::Process so it is ok to do this.
        size = m_max_memory_size;
    }

    char packet[64];
    const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size);
    assert (packet_len + 1 < sizeof(packet));
    StringExtractorGDBRemote response;
    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
    {
        if (response.IsNormalPacket())
        {
            error.Clear();
            return response.GetHexBytes(buf, size, '\xdd');
        }
        else if (response.IsErrorPacket())
            error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
        else if (response.IsUnsupportedPacket())
            error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
        else
            error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
    }
    else
    {
        error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet);
    }
    return 0;
}

size_t
ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
{
    StreamString packet;
    packet.Printf("M%llx,%zx:", addr, size);
    packet.PutBytesAsRawHex8(buf, size, eByteOrderHost, eByteOrderHost);
    StringExtractorGDBRemote response;
    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, 2, true))
    {
        if (response.IsOKPacket())
        {
            error.Clear();
            return size;
        }
        else if (response.IsErrorPacket())
            error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
        else if (response.IsUnsupportedPacket())
            error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
        else
            error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
    }
    else
    {
        error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str());
    }
    return 0;
}

lldb::addr_t
ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
{
    addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions, m_packet_timeout);
    if (allocated_addr == LLDB_INVALID_ADDRESS)
        error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions);
    else
        error.Clear();
    return allocated_addr;
}

Error
ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
{
    Error error; 
    if (!m_gdb_comm.DeallocateMemory (addr, m_packet_timeout))
        error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
    return error;
}


//------------------------------------------------------------------
// Process STDIO
//------------------------------------------------------------------

size_t
ProcessGDBRemote::GetSTDOUT (char *buf, size_t buf_size, Error &error)
{
    Mutex::Locker locker(m_stdio_mutex);
    size_t bytes_available = m_stdout_data.size();
    if (bytes_available > 0)
    {
        ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size);
        if (bytes_available > buf_size)
        {
            memcpy(buf, m_stdout_data.c_str(), buf_size);
            m_stdout_data.erase(0, buf_size);
            bytes_available = buf_size;
        }
        else
        {
            memcpy(buf, m_stdout_data.c_str(), bytes_available);
            m_stdout_data.clear();

            //ResetEventBits(eBroadcastBitSTDOUT);
        }
    }
    return bytes_available;
}

size_t
ProcessGDBRemote::GetSTDERR (char *buf, size_t buf_size, Error &error)
{
    // Can we get STDERR through the remote protocol?
    return 0;
}

size_t
ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
{
    if (m_stdio_communication.IsConnected())
    {
        ConnectionStatus status;
        m_stdio_communication.Write(src, src_len, status, NULL);
    }
    return 0;
}

Error
ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
{
    Error error;
    assert (bp_site != NULL);

    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS);
    user_id_t site_id = bp_site->GetID();
    const addr_t addr = bp_site->GetLoadAddress();
    if (log)
        log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx", site_id, (uint64_t)addr);

    if (bp_site->IsEnabled())
    {
        if (log)
            log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
        return error;
    }
    else
    {
        const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);

        if (bp_site->HardwarePreferred())
        {
            // Try and set hardware breakpoint, and if that fails, fall through
            // and set a software breakpoint?
        }

        if (m_z0_supported)
        {
            char packet[64];
            const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
            assert (packet_len + 1 < sizeof(packet));
            StringExtractorGDBRemote response;
            if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
            {
                if (response.IsUnsupportedPacket())
                {
                    // Disable z packet support and try again
                    m_z0_supported = 0;
                    return EnableBreakpoint (bp_site);
                }
                else if (response.IsOKPacket())
                {
                    bp_site->SetEnabled(true);
                    bp_site->SetType (BreakpointSite::eExternal);
                    return error;
                }
                else
                {
                    uint8_t error_byte = response.GetError();
                    if (error_byte)
                        error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
                }
            }
        }
        else
        {
            return EnableSoftwareBreakpoint (bp_site);
        }
    }

    if (log)
    {
        const char *err_string = error.AsCString();
        log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
                     bp_site->GetLoadAddress(),
                     err_string ? err_string : "NULL");
    }
    // We shouldn't reach here on a successful breakpoint enable...
    if (error.Success())
        error.SetErrorToGenericError();
    return error;
}

Error
ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
{
    Error error;
    assert (bp_site != NULL);
    addr_t addr = bp_site->GetLoadAddress();
    user_id_t site_id = bp_site->GetID();
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS);
    if (log)
        log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr);

    if (bp_site->IsEnabled())
    {
        const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);

        if (bp_site->IsHardware())
        {
            // TODO: disable hardware breakpoint...
        }
        else
        {
            if (m_z0_supported)
            {
                char packet[64];
                const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
                assert (packet_len + 1 < sizeof(packet));
                StringExtractorGDBRemote response;
                if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
                {
                    if (response.IsUnsupportedPacket())
                    {
                        error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
                    }
                    else if (response.IsOKPacket())
                    {
                        if (log)
                            log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
                        bp_site->SetEnabled(false);
                        return error;
                    }
                    else
                    {
                        uint8_t error_byte = response.GetError();
                        if (error_byte)
                            error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
                    }
                }
            }
            else
            {
                return DisableSoftwareBreakpoint (bp_site);
            }
        }
    }
    else
    {
        if (log)
            log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
        return error;
    }

    if (error.Success())
        error.SetErrorToGenericError();
    return error;
}

Error
ProcessGDBRemote::EnableWatchpoint (WatchpointLocation *wp)
{
    Error error;
    if (wp)
    {
        user_id_t watchID = wp->GetID();
        addr_t addr = wp->GetLoadAddress();
        Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS);
        if (log)
            log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %d)", watchID);
        if (wp->IsEnabled())
        {
            if (log)
                log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
            return error;
        }
        else
        {
            // Pass down an appropriate z/Z packet...
            error.SetErrorString("watchpoints not supported");
        }
    }
    else
    {
        error.SetErrorString("Watchpoint location argument was NULL.");
    }
    if (error.Success())
        error.SetErrorToGenericError();
    return error;
}

Error
ProcessGDBRemote::DisableWatchpoint (WatchpointLocation *wp)
{
    Error error;
    if (wp)
    {
        user_id_t watchID = wp->GetID();

        Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS);

        addr_t addr = wp->GetLoadAddress();
        if (log)
            log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr);

        if (wp->IsHardware())
        {
            // Pass down an appropriate z/Z packet...
            error.SetErrorString("watchpoints not supported");
        }
        // TODO: clear software watchpoints if we implement them
    }
    else
    {
        error.SetErrorString("Watchpoint location argument was NULL.");
    }
    if (error.Success())
        error.SetErrorToGenericError();
    return error;
}

void
ProcessGDBRemote::Clear()
{
    m_flags = 0;
    m_thread_list.Clear();
    {
        Mutex::Locker locker(m_stdio_mutex);
        m_stdout_data.clear();
    }
    DestoryLibUnwindAddressSpace();
}

Error
ProcessGDBRemote::DoSignal (int signo)
{
    Error error;
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
    if (log)
        log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);

    if (!m_gdb_comm.SendAsyncSignal (signo))
        error.SetErrorStringWithFormat("failed to send signal %i", signo);
    return error;
}

void
ProcessGDBRemote::STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len)
{
    ProcessGDBRemote *process = (ProcessGDBRemote *)baton;
    process->AppendSTDOUT(static_cast<const char *>(src), src_len);
}

void
ProcessGDBRemote::AppendSTDOUT (const char* s, size_t len)
{
    ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::%s (<%d> %s) ...", __FUNCTION__, len, s);
    Mutex::Locker locker(m_stdio_mutex);
    m_stdout_data.append(s, len);

    // FIXME: Make a real data object for this and put it out.
    BroadcastEventIfUnique (eBroadcastBitSTDOUT);
}


Error
ProcessGDBRemote::StartDebugserverProcess
(
    const char *debugserver_url,    // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
    char const *inferior_argv[],    // Arguments for the inferior program including the path to the inferior itself as the first argument
    char const *inferior_envp[],    // Environment to pass along to the inferior program
    char const *stdio_path,
    lldb::pid_t attach_pid,         // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID then attach to this attach_pid
    const char *attach_name,        // Wait for the next process to launch whose basename matches "attach_name"
    bool wait_for_launch,           // Wait for the process named "attach_name" to launch
    bool disable_aslr,               // Disable ASLR
    ArchSpec& inferior_arch         // The arch of the inferior that we will launch
)
{
    Error error;
    if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
    {
        // If we locate debugserver, keep that located version around
        static FileSpec g_debugserver_file_spec;

        FileSpec debugserver_file_spec;
        char debugserver_path[PATH_MAX];

        // 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);
        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. 
            FileSpec framework_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)lldb_private::Initialize));
            const char *framework_dir = framework_file_spec.GetDirectory().AsCString();
            const char *lldb_framework = ::strstr (framework_dir, "/LLDB.framework");

            if (lldb_framework)
            {
                int len = lldb_framework - framework_dir + strlen ("/LLDB.framework");
                ::snprintf (debugserver_path,
                            sizeof(debugserver_path),
                            "%.*s/Resources/%s",
                            len,
                            framework_dir,
                            DEBUGSERVER_BASENAME);
                debugserver_file_spec.SetFile (debugserver_path);
                debugserver_exists = debugserver_file_spec.Exists();
            }

            if (debugserver_exists)
            {
                g_debugserver_file_spec = debugserver_file_spec;
            }
            else
            {
                g_debugserver_file_spec.Clear();
                debugserver_file_spec.Clear();
            }
        }

        if (debugserver_exists)
        {
            debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));

            m_stdio_communication.Clear();
            posix_spawnattr_t attr;

            Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);

            Error local_err;    // Errors that don't affect the spawning.
            if (log)
                log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )", __FUNCTION__, debugserver_path, inferior_argv, inferior_envp, inferior_arch.AsCString());
            error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
            if (error.Fail() || log)
                error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
            if (error.Fail())
                return error;;

#if !defined (__arm__)

            // We don't need to do this for ARM, and we really shouldn't now that we
            // have multiple CPU subtypes and no posix_spawnattr call that allows us
            // to set which CPU subtype to launch...
            if (inferior_arch.GetType() == eArchTypeMachO)
            {
                cpu_type_t cpu = inferior_arch.GetCPUType();
                if (cpu != 0 && cpu != UINT32_MAX && cpu != LLDB_INVALID_CPUTYPE)
                {
                    size_t ocount = 0;
                    error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
                    if (error.Fail() || log)
                        error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu, ocount);

                    if (error.Fail() != 0 || ocount != 1)
                        return error;
                }
            }

#endif

            Args debugserver_args;
            char arg_cstr[PATH_MAX];
            bool launch_process = true;

            if (inferior_argv == NULL && attach_pid != LLDB_INVALID_PROCESS_ID)
                launch_process = false;
            else if (attach_name)
                launch_process = false; // Wait for a process whose basename matches that in inferior_argv[0]

            bool pass_stdio_path_to_debugserver = true;
            lldb_utility::PseudoTerminal pty;
            if (stdio_path == NULL)
            {
                pass_stdio_path_to_debugserver = false;
                if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
                {
                    struct termios stdin_termios;
                    if (::tcgetattr (pty.GetMasterFileDescriptor(), &stdin_termios) == 0)
                    {
                        stdin_termios.c_lflag &= ~ECHO;     // Turn off echoing
                        stdin_termios.c_lflag &= ~ICANON;   // Get one char at a time
                        ::tcsetattr (pty.GetMasterFileDescriptor(), TCSANOW, &stdin_termios);
                    }
                    stdio_path = pty.GetSlaveName (NULL, 0);
                }
            }

            // Start args with "debugserver /file/path -r --"
            debugserver_args.AppendArgument(debugserver_path);
            debugserver_args.AppendArgument(debugserver_url);
            debugserver_args.AppendArgument("--native-regs");   // use native registers, not the GDB registers
            debugserver_args.AppendArgument("--setsid");        // make debugserver run in its own session so
                                                        // signals generated by special terminal key
                                                        // sequences (^C) don't affect debugserver

            if (disable_aslr)
                debugserver_args.AppendArguments("--disable-aslr");
            
            // Only set the inferior
            if (launch_process)
            {
                if (stdio_path && pass_stdio_path_to_debugserver)
                {
                    debugserver_args.AppendArgument("-s");    // short for --stdio-path
                    StreamString strm;
                    strm.Printf("'%s'", stdio_path);
                    debugserver_args.AppendArgument(strm.GetData());    // path to file to have inferior open as it's STDIO
                }
            }

            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);
            }

            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);
            }
//            debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
//            debugserver_args.AppendArgument("--log-flags=0x800e0e");

            // Now append the program arguments
            if (launch_process)
            {
                if (inferior_argv)
                {
                    // Terminate the debugserver args so we can now append the inferior args
                    debugserver_args.AppendArgument("--");

                    for (int i = 0; inferior_argv[i] != NULL; ++i)
                        debugserver_args.AppendArgument (inferior_argv[i]);
                }
                else
                {
                    // Will send environment entries with the 'QEnvironment:' packet
                    // Will send arguments with the 'A' packet
                }
            }
            else if (attach_pid != LLDB_INVALID_PROCESS_ID)
            {
                ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
                debugserver_args.AppendArgument (arg_cstr);
            }
            else if (attach_name && attach_name[0])
            {
                if (wait_for_launch)
                    debugserver_args.AppendArgument ("--waitfor");
                else
                    debugserver_args.AppendArgument ("--attach");
                debugserver_args.AppendArgument (attach_name);
            }

            Error file_actions_err;
            posix_spawn_file_actions_t file_actions;
#if DONT_CLOSE_DEBUGSERVER_STDIO
            file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
#else
            file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
            if (file_actions_err.Success())
            {
                ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
                ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
                ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
            }
#endif

            if (log)
            {
                StreamString strm;
                debugserver_args.Dump (&strm);
                log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
            }

            error.SetError(::posix_spawnp (&m_debugserver_pid,
                                             debugserver_path,
                                             file_actions_err.Success() ? &file_actions : NULL,
                                             &attr,
                                             debugserver_args.GetArgumentVector(),
                                             (char * const*)inferior_envp),
                             eErrorTypePOSIX);


            ::posix_spawnattr_destroy (&attr);

            if (file_actions_err.Success())
                ::posix_spawn_file_actions_destroy (&file_actions);

            // We have seen some cases where posix_spawnp was returning a valid
            // looking pid even when an error was returned, so clear it out
            if (error.Fail())
                m_debugserver_pid = LLDB_INVALID_PROCESS_ID;

            if (error.Fail() || log)
                error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp);

//            if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
//            {
//                std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor (pty.ReleaseMasterFileDescriptor(), true));
//                if (conn_ap.get())
//                {
//                    m_stdio_communication.SetConnection(conn_ap.release());
//                    if (m_stdio_communication.IsConnected())
//                    {
//                        m_stdio_communication.SetReadThreadBytesReceivedCallback (STDIOReadThreadBytesReceived, this);
//                        m_stdio_communication.StartReadThread();
//                    }
//                }
//            }
        }
        else
        {
            error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n");
        }

        if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
            StartAsyncThread ();
    }
    return error;
}

bool
ProcessGDBRemote::MonitorDebugserverProcess
(
    void *callback_baton,
    lldb::pid_t debugserver_pid,
    int signo,          // Zero for no signal
    int exit_status     // Exit value of process if signal is zero
)
{
    // We pass in the ProcessGDBRemote inferior process it and name it
    // "gdb_remote_pid". The process ID is passed in the "callback_baton"
    // pointer value itself, thus we need the double cast...

    // "debugserver_pid" argument passed in is the process ID for
    // debugserver that we are tracking...

    ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
    
    if (process)
    {
        // Sleep for a half a second to make sure our inferior process has
        // time to set its exit status before we set it incorrectly when
        // both the debugserver and the inferior process shut down.
        usleep (500000);
        // If our process hasn't yet exited, debugserver might have died.
        // If the process did exit, the we are reaping it.
        if (process->GetState() != eStateExited)
        {
            char error_str[1024];
            if (signo)
            {
                const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
                if (signal_cstr)
                    ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
                else
                    ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
            }
            else
            {
                ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
            }

            process->SetExitStatus (-1, error_str);
        }
        else
        {
            // Debugserver has exited we need to let our ProcessGDBRemote
            // know that it no longer has a debugserver instance
            process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
            // We are returning true to this function below, so we can
            // forget about the monitor handle.
            process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
        }
    }
    return true;
}

void
ProcessGDBRemote::KillDebugserverProcess ()
{
    if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
    {
        ::kill (m_debugserver_pid, SIGINT);
        m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
    }
}

void
ProcessGDBRemote::Initialize()
{
    static bool g_initialized = false;

    if (g_initialized == false)
    {
        g_initialized = true;
        PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                       GetPluginDescriptionStatic(),
                                       CreateInstance);

        Log::Callbacks log_callbacks = {
            ProcessGDBRemoteLog::DisableLog,
            ProcessGDBRemoteLog::EnableLog,
            ProcessGDBRemoteLog::ListLogCategories
        };

        Log::RegisterLogChannel (ProcessGDBRemote::GetPluginNameStatic(), log_callbacks);
    }
}

bool
ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
{
    if (m_curr_tid == tid)
        return true;

    char packet[32];
    const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
    assert (packet_len + 1 < sizeof(packet));
    StringExtractorGDBRemote response;
    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
    {
        if (response.IsOKPacket())
        {
            m_curr_tid = tid;
            return true;
        }
    }
    return false;
}

bool
ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
{
    if (m_curr_tid_run == tid)
        return true;

    char packet[32];
    const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
    assert (packet_len + 1 < sizeof(packet));
    StringExtractorGDBRemote response;
    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
    {
        if (response.IsOKPacket())
        {
            m_curr_tid_run = tid;
            return true;
        }
    }
    return false;
}

void
ProcessGDBRemote::ResetGDBRemoteState ()
{
    // Reset and GDB remote state
    m_curr_tid = LLDB_INVALID_THREAD_ID;
    m_curr_tid_run = LLDB_INVALID_THREAD_ID;
    m_z0_supported = 1;
}


bool
ProcessGDBRemote::StartAsyncThread ()
{
    ResetGDBRemoteState ();

    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);

    if (log)
        log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);

    // Create a thread that watches our internal state and controls which
    // events make it to clients (into the DCProcess event queue).
    m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
    return m_async_thread != LLDB_INVALID_HOST_THREAD;
}

void
ProcessGDBRemote::StopAsyncThread ()
{
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);

    if (log)
        log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);

    m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);

    // Stop the stdio thread
    if (m_async_thread != LLDB_INVALID_HOST_THREAD)
    {
        Host::ThreadJoin (m_async_thread, NULL, NULL);
    }
}


void *
ProcessGDBRemote::AsyncThread (void *arg)
{
    ProcessGDBRemote *process = (ProcessGDBRemote*) arg;

    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
    if (log)
        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());

    Listener listener ("ProcessGDBRemote::AsyncThread");
    EventSP event_sp;
    const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
                                        eBroadcastBitAsyncThreadShouldExit;

    if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
    {
        bool done = false;
        while (!done)
        {
            if (log)
                log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
            if (listener.WaitForEvent (NULL, event_sp))
            {
                const uint32_t event_type = event_sp->GetType();
                switch (event_type)
                {
                    case eBroadcastBitAsyncContinue:
                        {
                            const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());

                            if (continue_packet)
                            {
                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
                                if (log)
                                    log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);

                                process->SetPrivateState(eStateRunning);
                                StringExtractorGDBRemote response;
                                StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);

                                switch (stop_state)
                                {
                                case eStateStopped:
                                case eStateCrashed:
                                case eStateSuspended:
                                    process->m_last_stop_packet = response;
                                    process->m_last_stop_packet.SetFilePos (0);
                                    process->SetPrivateState (stop_state);
                                    break;

                                case eStateExited:
                                    process->m_last_stop_packet = response;
                                    process->m_last_stop_packet.SetFilePos (0);
                                    response.SetFilePos(1);
                                    process->SetExitStatus(response.GetHexU8(), NULL);
                                    done = true;
                                    break;

                                case eStateInvalid:
                                    break;

                                default:
                                    process->SetPrivateState (stop_state);
                                    break;
                                }
                            }
                        }
                        break;

                    case eBroadcastBitAsyncThreadShouldExit:
                        if (log)
                            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
                        done = true;
                        break;

                    default:
                        if (log)
                            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
                        done = true;
                        break;
                }
            }
            else
            {
                if (log)
                    log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
                done = true;
            }
        }
    }

    if (log)
        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());

    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
    return NULL;
}

lldb_private::unw_addr_space_t
ProcessGDBRemote::GetLibUnwindAddressSpace ()
{
    unw_targettype_t target_type = UNW_TARGET_UNSPECIFIED;

    ArchSpec::CPU arch_cpu = m_target.GetArchitecture().GetGenericCPUType();
    if (arch_cpu == ArchSpec::eCPU_i386)
        target_type = UNW_TARGET_I386;
    else if (arch_cpu == ArchSpec::eCPU_x86_64)
        target_type = UNW_TARGET_X86_64;

    if (m_libunwind_addr_space)
    {
        if (m_libunwind_target_type != target_type)
            DestoryLibUnwindAddressSpace();
        else
            return m_libunwind_addr_space;
    }
    unw_accessors_t callbacks = get_macosx_libunwind_callbacks ();
    m_libunwind_addr_space = unw_create_addr_space (&callbacks, target_type);
    if (m_libunwind_addr_space)
        m_libunwind_target_type = target_type;
    else
        m_libunwind_target_type = UNW_TARGET_UNSPECIFIED;
    return m_libunwind_addr_space;
}

void
ProcessGDBRemote::DestoryLibUnwindAddressSpace ()
{
    if (m_libunwind_addr_space)
    {
        unw_destroy_addr_space (m_libunwind_addr_space);
        m_libunwind_addr_space = NULL;
    }
    m_libunwind_target_type = UNW_TARGET_UNSPECIFIED;
}


const char *
ProcessGDBRemote::GetDispatchQueueNameForThread
(
    addr_t thread_dispatch_qaddr,
    std::string &dispatch_queue_name
)
{
    dispatch_queue_name.clear();
    if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
    {
        // Cache the dispatch_queue_offsets_addr value so we don't always have
        // to look it up
        if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
        {
            ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib")));
            if (module_sp.get() == NULL)
                return NULL;

            const Symbol *dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (ConstString("dispatch_queue_offsets"), eSymbolTypeData);
            if (dispatch_queue_offsets_symbol)
                m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(&m_target);

            if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
                return NULL;
        }

        uint8_t memory_buffer[8];
        DataExtractor data(memory_buffer, sizeof(memory_buffer), GetByteOrder(), GetAddressByteSize());

        // Excerpt from src/queue_private.h
        struct dispatch_queue_offsets_s
        {
            uint16_t dqo_version;
            uint16_t dqo_label;
            uint16_t dqo_label_size;
        } dispatch_queue_offsets;


        Error error;
        if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
        {
            uint32_t data_offset = 0;
            if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
            {
                if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
                {
                    data_offset = 0;
                    lldb::addr_t queue_addr = data.GetAddress(&data_offset);
                    lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
                    dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
                    size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
                    if (bytes_read < dispatch_queue_offsets.dqo_label_size)
                        dispatch_queue_name.erase (bytes_read);
                }
            }
        }
    }
    if (dispatch_queue_name.empty())
        return NULL;
    return dispatch_queue_name.c_str();
}

uint32_t
ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
{
    // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
    // process and ask it for the list of processes. But if we are local, we can let the Host do it.
    if (m_local_debugserver)
    {
        return Host::ListProcessesMatchingName (name, matches, pids);
    }
    else 
    {
        // FIXME: Implement talking to the remote debugserver.
        return 0;
    }

}
