//===-- MachProcess.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/15/07.
//
//===----------------------------------------------------------------------===//

#include "DNB.h"
#include <mach/mach.h>
#include <spawn.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <unistd.h>
#include "MacOSX/CFUtils.h"
#include "SysSignal.h"

#include <algorithm>
#include <map>

#include "DNBDataRef.h"
#include "DNBLog.h"
#include "DNBThreadResumeActions.h"
#include "DNBTimer.h"
#include "MachProcess.h"
#include "PseudoTerminal.h"

#include "CFBundle.h"
#include "CFData.h"
#include "CFString.h"

static CFStringRef CopyBundleIDForPath (const char *app_buncle_path, DNBError &err_str);

#if defined (__arm__)

#include <CoreFoundation/CoreFoundation.h>
#include <SpringBoardServices/SpringBoardServer.h>
#include <SpringBoardServices/SBSWatchdogAssertion.h>


static bool
IsSBProcess (nub_process_t pid)
{
    bool opt_runningApps = true;
    bool opt_debuggable = false;

    CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));
    if (sbsAppIDs.get() != NULL)
    {
        CFIndex count = ::CFArrayGetCount (sbsAppIDs.get());
        CFIndex i = 0;
        for (i = 0; i < count; i++)
        {
            CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);

            // Get the process id for the app (if there is one)
            pid_t sbs_pid = INVALID_NUB_PROCESS;
            if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &sbs_pid) == TRUE)
            {
                if (sbs_pid == pid)
                    return true;
            }
        }
    }
    return false;
}


#endif

#if 0
#define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
#else
#define DEBUG_LOG(fmt, ...)
#endif

#ifndef MACH_PROCESS_USE_POSIX_SPAWN
#define MACH_PROCESS_USE_POSIX_SPAWN 1
#endif

#ifndef _POSIX_SPAWN_DISABLE_ASLR
#define _POSIX_SPAWN_DISABLE_ASLR       0x0100
#endif

MachProcess::MachProcess() :
    m_pid               (0),
    m_cpu_type          (0),
    m_child_stdin       (-1),
    m_child_stdout      (-1),
    m_child_stderr      (-1),
    m_path              (),
    m_args              (),
    m_task              (this),
    m_flags             (eMachProcessFlagsNone),
    m_stdio_thread      (0),
    m_stdio_mutex       (PTHREAD_MUTEX_RECURSIVE),
    m_stdout_data       (),
    m_thread_actions    (),
    m_thread_list        (),
    m_exception_messages (),
    m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE),
    m_state             (eStateUnloaded),
    m_state_mutex       (PTHREAD_MUTEX_RECURSIVE),
    m_events            (0, kAllEventsMask),
    m_breakpoints       (),
    m_watchpoints       (),
    m_name_to_addr_callback(NULL),
    m_name_to_addr_baton(NULL),
    m_image_infos_callback(NULL),
    m_image_infos_baton(NULL)
{
    DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
}

MachProcess::~MachProcess()
{
    DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
    Clear();
}

pid_t
MachProcess::SetProcessID(pid_t pid)
{
    // Free any previous process specific data or resources
    Clear();
    // Set the current PID appropriately
    if (pid == 0)
        m_pid = ::getpid ();
    else
        m_pid = pid;
    return m_pid;    // Return actualy PID in case a zero pid was passed in
}

nub_state_t
MachProcess::GetState()
{
    // If any other threads access this we will need a mutex for it
    PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
    return m_state;
}

const char *
MachProcess::ThreadGetName(nub_thread_t tid)
{
    return m_thread_list.GetName(tid);
}

nub_state_t
MachProcess::ThreadGetState(nub_thread_t tid)
{
    return m_thread_list.GetState(tid);
}


nub_size_t
MachProcess::GetNumThreads () const
{
    return m_thread_list.NumThreads();
}

nub_thread_t
MachProcess::GetThreadAtIndex (nub_size_t thread_idx) const
{
    return m_thread_list.ThreadIDAtIndex(thread_idx);
}

nub_thread_t
MachProcess::GetCurrentThread ()
{
    return m_thread_list.CurrentThreadID();
}

nub_thread_t
MachProcess::SetCurrentThread(nub_thread_t tid)
{
    return m_thread_list.SetCurrentThread(tid);
}

bool
MachProcess::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const
{
    return m_thread_list.GetThreadStoppedReason(tid, stop_info);
}

void
MachProcess::DumpThreadStoppedReason(nub_thread_t tid) const
{
    return m_thread_list.DumpThreadStoppedReason(tid);
}

const char *
MachProcess::GetThreadInfo(nub_thread_t tid) const
{
    return m_thread_list.GetThreadInfo(tid);
}

uint32_t
MachProcess::GetCPUType ()
{
    if (m_cpu_type == 0 && m_pid != 0)
        m_cpu_type = MachProcess::GetCPUTypeForLocalProcess (m_pid);
    return m_cpu_type;
}

const DNBRegisterSetInfo *
MachProcess::GetRegisterSetInfo (nub_thread_t tid, nub_size_t *num_reg_sets) const
{
    MachThreadSP thread_sp (m_thread_list.GetThreadByID (tid));
    if (thread_sp)
    {
        DNBArchProtocol *arch = thread_sp->GetArchProtocol();
        if (arch)
            return arch->GetRegisterSetInfo (num_reg_sets);
    }
    *num_reg_sets = 0;
    return NULL;
}

bool
MachProcess::GetRegisterValue ( nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *value ) const
{
    return m_thread_list.GetRegisterValue(tid, set, reg, value);
}

bool
MachProcess::SetRegisterValue ( nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *value ) const
{
    return m_thread_list.SetRegisterValue(tid, set, reg, value);
}

void
MachProcess::SetState(nub_state_t new_state)
{
    // If any other threads access this we will need a mutex for it
    uint32_t event_mask = 0;

    // Scope for mutex locker
    {
        PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SetState ( %s )", DNBStateAsString(new_state));

        const nub_state_t old_state = m_state;

        if (old_state != new_state)
        {
            if (NUB_STATE_IS_STOPPED(new_state))
                event_mask = eEventProcessStoppedStateChanged;
            else
                event_mask = eEventProcessRunningStateChanged;

            m_state = new_state;
            if (new_state == eStateStopped)
                m_stop_count++;
        }
    }

    if (event_mask != 0)
    {
        m_events.SetEvents (event_mask);

        // Wait for the event bit to reset if a reset ACK is requested
        m_events.WaitForResetAck(event_mask);
    }

}

void
MachProcess::Clear()
{
    // Clear any cached thread list while the pid and task are still valid

    m_task.Clear();
    // Now clear out all member variables
    m_pid = INVALID_NUB_PROCESS;
    CloseChildFileDescriptors();
    m_path.clear();
    m_args.clear();
    SetState(eStateUnloaded);
    m_flags = eMachProcessFlagsNone;
    m_stop_count = 0;
    m_thread_list.Clear();
    {
        PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
        m_exception_messages.clear();
    }
}


bool
MachProcess::StartSTDIOThread()
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__);
    // Create the thread that watches for the child STDIO
    return ::pthread_create (&m_stdio_thread, NULL, MachProcess::STDIOThread, this) == 0;
}


nub_addr_t
MachProcess::LookupSymbol(const char *name, const char *shlib)
{
    if (m_name_to_addr_callback != NULL && name && name[0])
        return m_name_to_addr_callback(ProcessID(), name, shlib, m_name_to_addr_baton);
    return INVALID_NUB_ADDRESS;
}

bool
MachProcess::Resume (const DNBThreadResumeActions& thread_actions)
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Resume ()");
    nub_state_t state = GetState();

    if (CanResume(state))
    {
        m_thread_actions = thread_actions;
        PrivateResume();
        return true;
    }
    else if (state == eStateRunning)
    {
        DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x is running, ignoring...", m_task.TaskPort());
        return true;
    }
    DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", m_task.TaskPort());
    return false;
}

bool
MachProcess::Kill (const struct timespec *timeout_abstime)
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill ()");
    nub_state_t state = DoSIGSTOP(true);
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() state = %s", DNBStateAsString(state));
    errno = 0;
    ::ptrace (PT_KILL, m_pid, 0, 0);
    DNBError err;
    err.SetErrorToErrno();
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", err.Error(), err.AsString());
    m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
    PrivateResume ();
    return true;
}

bool
MachProcess::Signal (int signal, const struct timespec *timeout_abstime)
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p)", signal, timeout_abstime);
    nub_state_t state = GetState();
    if (::kill (ProcessID(), signal) == 0)
    {
        // If we were running and we have a timeout, wait for the signal to stop
        if (IsRunning(state) && timeout_abstime)
        {
            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) waiting for signal to stop process...", signal, timeout_abstime);
            m_events.WaitForSetEvents(eEventProcessStoppedStateChanged, timeout_abstime);
            state = GetState();
            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) state = %s", signal, timeout_abstime, DNBStateAsString(state));
            return !IsRunning (state);
        }
        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) not waiting...", signal, timeout_abstime);
        return true;
    }
    DNBError err(errno, DNBError::POSIX);
    err.LogThreadedIfError("kill (pid = %d, signo = %i)", ProcessID(), signal);
    return false;

}

nub_state_t
MachProcess::DoSIGSTOP (bool clear_bps_and_wps, uint32_t *thread_idx_ptr)
{
    nub_state_t state = GetState();
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s", DNBStateAsString (state));

    if (!IsRunning(state))
    {
        if (clear_bps_and_wps)
        {
            DisableAllBreakpoints (true);
            DisableAllWatchpoints (true);
            clear_bps_and_wps = false;
        }

        // If we already have a thread stopped due to a SIGSTOP, we don't have
        // to do anything...
        uint32_t thread_idx = m_thread_list.GetThreadIndexForThreadStoppedWithSignal (SIGSTOP);
        if (thread_idx_ptr)
            *thread_idx_ptr = thread_idx;
        if (thread_idx != UINT32_MAX)
            return GetState();

        // No threads were stopped with a SIGSTOP, we need to run and halt the
        // process with a signal
        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- resuming process", DNBStateAsString (state));
        m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
        PrivateResume ();

        // Reset the event that says we were indeed running
        m_events.ResetEvents(eEventProcessRunningStateChanged);
        state = GetState();
    }

    // We need to be stopped in order to be able to detach, so we need
    // to send ourselves a SIGSTOP

    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- sending SIGSTOP", DNBStateAsString (state));
    struct timespec sigstop_timeout;
    DNBTimer::OffsetTimeOfDay(&sigstop_timeout, 2, 0);
    Signal (SIGSTOP, &sigstop_timeout);
    if (clear_bps_and_wps)
    {
        DisableAllBreakpoints (true);
        DisableAllWatchpoints (true);
        clear_bps_and_wps = false;
    }
    uint32_t thread_idx = m_thread_list.GetThreadIndexForThreadStoppedWithSignal (SIGSTOP);
    if (thread_idx_ptr)
        *thread_idx_ptr = thread_idx;
    return GetState();
}

bool
MachProcess::Detach()
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach()");

    uint32_t thread_idx = UINT32_MAX;
    nub_state_t state = DoSIGSTOP(true, &thread_idx);
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach() DoSIGSTOP() returned %s", DNBStateAsString(state));

    {
        m_thread_actions.Clear();
        DNBThreadResumeAction thread_action;
        thread_action.tid = m_thread_list.ThreadIDAtIndex (thread_idx);
        thread_action.state = eStateRunning;
        thread_action.signal = -1;
        thread_action.addr = INVALID_NUB_ADDRESS;
        
        m_thread_actions.Append (thread_action);
        m_thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
        
        PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);

        ReplyToAllExceptions ();

    }

    m_task.ShutDownExcecptionThread();

    // Detach from our process
    errno = 0;
    nub_process_t pid = m_pid;
    int ret = ::ptrace (PT_DETACH, pid, (caddr_t)1, 0);
    DNBError err(errno, DNBError::POSIX);
    if (DNBLogCheckLogBit(LOG_PROCESS) || err.Fail() || (ret != 0))
        err.LogThreaded("::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid);

    // Resume our task
    m_task.Resume();

    // NULL our task out as we have already retored all exception ports
    m_task.Clear();

    // Clear out any notion of the process we once were
    Clear();

    SetState(eStateDetached);

    return true;
}


nub_size_t
MachProcess::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const
{
    nub_size_t bytes_removed = 0;
    const DNBBreakpoint *bp;
    nub_addr_t intersect_addr;
    nub_size_t intersect_size;
    nub_size_t opcode_offset;
    nub_size_t idx;
    for (idx = 0; (bp = m_breakpoints.GetByIndex(idx)) != NULL; ++idx)
    {
        if (bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset))
        {
            assert(addr <= intersect_addr && intersect_addr < addr + size);
            assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
            assert(opcode_offset + intersect_size <= bp->ByteSize());
            nub_size_t buf_offset = intersect_addr - addr;
            ::memcpy(buf + buf_offset, bp->SavedOpcodeBytes() + opcode_offset, intersect_size);
        }
    }
    return bytes_removed;
}

//----------------------------------------------------------------------
// ReadMemory from the MachProcess level will always remove any software
// breakpoints from the memory buffer before returning. If you wish to
// read memory and see those traps, read from the MachTask
// (m_task.ReadMemory()) as that version will give you what is actually
// in inferior memory.
//----------------------------------------------------------------------
nub_size_t
MachProcess::ReadMemory (nub_addr_t addr, nub_size_t size, void *buf)
{
    // We need to remove any current software traps (enabled software
    // breakpoints) that we may have placed in our tasks memory.

    // First just read the memory as is
    nub_size_t bytes_read = m_task.ReadMemory(addr, size, buf);

    // Then place any opcodes that fall into this range back into the buffer
    // before we return this to callers.
    if (bytes_read > 0)
        RemoveTrapsFromBuffer (addr, size, (uint8_t *)buf);
    return bytes_read;
}

//----------------------------------------------------------------------
// WriteMemory from the MachProcess level will always write memory around
// any software breakpoints. Any software breakpoints will have their
// opcodes modified if they are enabled. Any memory that doesn't overlap
// with software breakpoints will be written to. If you wish to write to
// inferior memory without this interference, then write to the MachTask
// (m_task.WriteMemory()) as that version will always modify inferior
// memory.
//----------------------------------------------------------------------
nub_size_t
MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
{
    // We need to write any data that would go where any current software traps
    // (enabled software breakpoints) any software traps (breakpoints) that we
    // may have placed in our tasks memory.

    std::map<nub_addr_t, DNBBreakpoint *> addr_to_bp_map;
    DNBBreakpoint *bp;
    nub_size_t idx;
    for (idx = 0; (bp = m_breakpoints.GetByIndex(idx)) != NULL; ++idx)
    {
        if (bp->IntersectsRange(addr, size, NULL, NULL, NULL))
            addr_to_bp_map[bp->Address()] = bp;
    }

    // If we don't have any software breakpoints that are in this buffer, then
    // we can just write memory and be done with it.
    if (addr_to_bp_map.empty())
        return m_task.WriteMemory(addr, size, buf);

    // If we make it here, we have some breakpoints that overlap and we need
    // to work around them.

    nub_size_t bytes_written = 0;
    nub_addr_t intersect_addr;
    nub_size_t intersect_size;
    nub_size_t opcode_offset;
    const uint8_t *ubuf = (const uint8_t *)buf;
    std::map<nub_addr_t, DNBBreakpoint *>::iterator pos, end = addr_to_bp_map.end();
    for (pos = addr_to_bp_map.begin(); pos != end; ++pos)
    {
        bp = pos->second;

        assert(bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset));
        assert(addr <= intersect_addr && intersect_addr < addr + size);
        assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
        assert(opcode_offset + intersect_size <= bp->ByteSize());

        // Check for bytes before this breakpoint
        const nub_addr_t curr_addr = addr + bytes_written;
        if (intersect_addr > curr_addr)
        {
            // There are some bytes before this breakpoint that we need to
            // just write to memory
            nub_size_t curr_size = intersect_addr - curr_addr;
            nub_size_t curr_bytes_written = m_task.WriteMemory(curr_addr, curr_size, ubuf + bytes_written);
            bytes_written += curr_bytes_written;
            if (curr_bytes_written != curr_size)
            {
                // We weren't able to write all of the requested bytes, we
                // are done looping and will return the number of bytes that
                // we have written so far.
                break;
            }
        }

        // Now write any bytes that would cover up any software breakpoints
        // directly into the breakpoint opcode buffer
        ::memcpy(bp->SavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
        bytes_written += intersect_size;
    }

    // Write any remaining bytes after the last breakpoint if we have any left
    if (bytes_written < size)
        bytes_written += m_task.WriteMemory(addr + bytes_written, size - bytes_written, ubuf + bytes_written);

    return bytes_written;
}


void
MachProcess::ReplyToAllExceptions ()
{
    PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
    if (m_exception_messages.empty() == false)
    {
        MachException::Message::iterator pos;
        MachException::Message::iterator begin = m_exception_messages.begin();
        MachException::Message::iterator end = m_exception_messages.end();
        for (pos = begin; pos != end; ++pos)
        {
            DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %d...", std::distance(begin, pos));
            int thread_reply_signal = 0;

            const DNBThreadResumeAction *action = m_thread_actions.GetActionForThread (pos->state.thread_port, false);

            if (action)
            {
                thread_reply_signal = action->signal;
                if (thread_reply_signal)
                    m_thread_actions.SetSignalHandledForThread (pos->state.thread_port);
            }

            DNBError err (pos->Reply(this, thread_reply_signal));
            if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
                err.LogThreadedIfError("Error replying to exception");
        }

        // Erase all exception message as we should have used and replied
        // to them all already.
        m_exception_messages.clear();
    }
}
void
MachProcess::PrivateResume ()
{
    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);

    ReplyToAllExceptions ();
//    bool stepOverBreakInstruction = step;

    // Let the thread prepare to resume and see if any threads want us to
    // step over a breakpoint instruction (ProcessWillResume will modify
    // the value of stepOverBreakInstruction).
    m_thread_list.ProcessWillResume (this, m_thread_actions);

    // Set our state accordingly
    if (m_thread_actions.NumActionsWithState(eStateStepping))
        SetState (eStateStepping);
    else
        SetState (eStateRunning);

    // Now resume our task.
    m_task.Resume();
}

nub_break_t
MachProcess::CreateBreakpoint(nub_addr_t addr, nub_size_t length, bool hardware, thread_t tid)
{
    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %u, hardware = %i, tid = 0x%4.4x )", (uint64_t)addr, length, hardware, tid);
    if (hardware && tid == INVALID_NUB_THREAD)
        tid = GetCurrentThread();

    DNBBreakpoint bp(addr, length, tid, hardware);
    nub_break_t breakID = m_breakpoints.Add(bp);
    if (EnableBreakpoint(breakID))
    {
        DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %u, tid = 0x%4.4x ) => %u", (uint64_t)addr, length, tid, breakID);
        return breakID;
    }
    else
    {
        m_breakpoints.Remove(breakID);
    }
    // We failed to enable the breakpoint
    return INVALID_NUB_BREAK_ID;
}

nub_watch_t
MachProcess::CreateWatchpoint(nub_addr_t addr, nub_size_t length, uint32_t watch_flags, bool hardware, thread_t tid)
{
    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %u, flags = 0x%8.8x, hardware = %i, tid = 0x%4.4x )", (uint64_t)addr, length, watch_flags, hardware, tid);
    if (hardware && tid == INVALID_NUB_THREAD)
        tid = GetCurrentThread();

    DNBBreakpoint watch(addr, length, tid, hardware);
    watch.SetIsWatchpoint(watch_flags);

    nub_watch_t watchID = m_watchpoints.Add(watch);
    if (EnableWatchpoint(watchID))
    {
        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %u, tid = 0x%x) => %u", (uint64_t)addr, length, tid, watchID);
        return watchID;
    }
    else
    {
        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %u, tid = 0x%x) => FAILED (%u)", (uint64_t)addr, length, tid, watchID);
        m_watchpoints.Remove(watchID);
    }
    // We failed to enable the watchpoint
    return INVALID_NUB_BREAK_ID;
}

nub_size_t
MachProcess::DisableAllBreakpoints(bool remove)
{
    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
    DNBBreakpoint *bp;
    nub_size_t disabled_count = 0;
    nub_size_t idx = 0;
    while ((bp = m_breakpoints.GetByIndex(idx)) != NULL)
    {
        bool success = DisableBreakpoint(bp->GetID(), remove);

        if (success)
            disabled_count++;
        // If we failed to disable the breakpoint or we aren't removing the breakpoint
        // increment the breakpoint index. Otherwise DisableBreakpoint will have removed
        // the breakpoint at this index and we don't need to change it.
        if ((success == false) || (remove == false))
            idx++;
    }
    return disabled_count;
}

nub_size_t
MachProcess::DisableAllWatchpoints(bool remove)
{
    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
    DNBBreakpoint *wp;
    nub_size_t disabled_count = 0;
    nub_size_t idx = 0;
    while ((wp = m_watchpoints.GetByIndex(idx)) != NULL)
    {
        bool success = DisableWatchpoint(wp->GetID(), remove);

        if (success)
            disabled_count++;
        // If we failed to disable the watchpoint or we aren't removing the watchpoint
        // increment the watchpoint index. Otherwise DisableWatchpoint will have removed
        // the watchpoint at this index and we don't need to change it.
        if ((success == false) || (remove == false))
            idx++;
    }
    return disabled_count;
}

bool
MachProcess::DisableBreakpoint(nub_break_t breakID, bool remove)
{
    DNBBreakpoint *bp = m_breakpoints.FindByID (breakID);
    if (bp)
    {
        nub_addr_t addr = bp->Address();
        DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx", breakID, remove, (uint64_t)addr);

        if (bp->IsHardware())
        {
            bool hw_disable_result = m_thread_list.DisableHardwareBreakpoint (bp);

            if (hw_disable_result == true)
            {
                bp->SetEnabled(false);
                // Let the thread list know that a breakpoint has been modified
                if (remove)
                {
                    m_thread_list.NotifyBreakpointChanged(bp);
                    m_breakpoints.Remove(breakID);
                }
                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx (hardware) => success", breakID, remove, (uint64_t)addr);
                return true;
            }

            return false;
        }

        const nub_size_t break_op_size = bp->ByteSize();
        assert (break_op_size > 0);
        const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (bp->ByteSize());
        if (break_op_size > 0)
        {
            // Clear a software breakoint instruction
            uint8_t curr_break_op[break_op_size];
            bool break_op_found = false;

            // Read the breakpoint opcode
            if (m_task.ReadMemory(addr, break_op_size, curr_break_op) == break_op_size)
            {
                bool verify = false;
                if (bp->IsEnabled())
                {
                    // Make sure we have the a breakpoint opcode exists at this address
                    if (memcmp(curr_break_op, break_op, break_op_size) == 0)
                    {
                        break_op_found = true;
                        // We found a valid breakpoint opcode at this address, now restore
                        // the saved opcode.
                        if (m_task.WriteMemory(addr, break_op_size, bp->SavedOpcodeBytes()) == break_op_size)
                        {
                            verify = true;
                        }
                        else
                        {
                            DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx memory write failed when restoring original opcode", breakID, remove, (uint64_t)addr);
                        }
                    }
                    else
                    {
                        DNBLogWarning("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx expected a breakpoint opcode but didn't find one.", breakID, remove, (uint64_t)addr);
                        // Set verify to true and so we can check if the original opcode has already been restored
                        verify = true;
                    }
                }
                else
                {
                    DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x$8.8llx is not enabled", breakID, remove, (uint64_t)addr);
                    // Set verify to true and so we can check if the original opcode is there
                    verify = true;
                }

                if (verify)
                {
                    uint8_t verify_opcode[break_op_size];
                    // Verify that our original opcode made it back to the inferior
                    if (m_task.ReadMemory(addr, break_op_size, verify_opcode) == break_op_size)
                    {
                        // compare the memory we just read with the original opcode
                        if (memcmp(bp->SavedOpcodeBytes(), verify_opcode, break_op_size) == 0)
                        {
                            // SUCCESS
                            bp->SetEnabled(false);
                            // Let the thread list know that a breakpoint has been modified
                            if (remove)
                            {
                                m_thread_list.NotifyBreakpointChanged(bp);
                                m_breakpoints.Remove(breakID);
                            }
                            DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx => success", breakID, remove, (uint64_t)addr);
                            return true;
                        }
                        else
                        {
                            if (break_op_found)
                                DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx: failed to restore original opcode", breakID, remove, (uint64_t)addr);
                            else
                                DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) addr = 0x%8.8llx: opcode changed", breakID, remove, (uint64_t)addr);
                        }
                    }
                    else
                    {
                        DNBLogWarning("MachProcess::DisableBreakpoint: unable to disable breakpoint 0x%8.8llx", (uint64_t)addr);
                    }
                }
            }
            else
            {
                DNBLogWarning("MachProcess::DisableBreakpoint: unable to read memory at 0x%8.8llx", (uint64_t)addr);
            }
        }
    }
    else
    {
        DNBLogError("MachProcess::DisableBreakpoint ( breakID = %d, remove = %d ) invalid breakpoint ID", breakID, remove);
    }
    return false;
}

bool
MachProcess::DisableWatchpoint(nub_watch_t watchID, bool remove)
{
    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s(watchID = %d, remove = %d)", __FUNCTION__, watchID, remove);
    DNBBreakpoint *wp = m_watchpoints.FindByID (watchID);
    if (wp)
    {
        nub_addr_t addr = wp->Address();
        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::DisableWatchpoint ( watchID = %d, remove = %d ) addr = 0x%8.8llx", watchID, remove, (uint64_t)addr);

        if (wp->IsHardware())
        {
            bool hw_disable_result = m_thread_list.DisableHardwareWatchpoint (wp);

            if (hw_disable_result == true)
            {
                wp->SetEnabled(false);
                if (remove)
                    m_watchpoints.Remove(watchID);
                DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::Disablewatchpoint ( watchID = %d, remove = %d ) addr = 0x%8.8llx (hardware) => success", watchID, remove, (uint64_t)addr);
                return true;
            }
        }

        // TODO: clear software watchpoints if we implement them
    }
    else
    {
        DNBLogError("MachProcess::DisableWatchpoint ( watchID = %d, remove = %d ) invalid watchpoint ID", watchID, remove);
    }
    return false;
}


void
MachProcess::DumpBreakpoint(nub_break_t breakID) const
{
    DNBLogThreaded("MachProcess::DumpBreakpoint(breakID = %d)", breakID);

    if (NUB_BREAK_ID_IS_VALID(breakID))
    {
        const DNBBreakpoint *bp = m_breakpoints.FindByID(breakID);
        if (bp)
            bp->Dump();
        else
            DNBLog("MachProcess::DumpBreakpoint(breakID = %d): invalid breakID", breakID);
    }
    else
    {
        m_breakpoints.Dump();
    }
}

void
MachProcess::DumpWatchpoint(nub_watch_t watchID) const
{
    DNBLogThreaded("MachProcess::DumpWatchpoint(watchID = %d)", watchID);

    if (NUB_BREAK_ID_IS_VALID(watchID))
    {
        const DNBBreakpoint *wp = m_watchpoints.FindByID(watchID);
        if (wp)
            wp->Dump();
        else
            DNBLog("MachProcess::DumpWatchpoint(watchID = %d): invalid watchID", watchID);
    }
    else
    {
        m_watchpoints.Dump();
    }
}

bool
MachProcess::EnableBreakpoint(nub_break_t breakID)
{
    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( breakID = %d )", breakID);
    DNBBreakpoint *bp = m_breakpoints.FindByID (breakID);
    if (bp)
    {
        nub_addr_t addr = bp->Address();
        if (bp->IsEnabled())
        {
            DNBLogWarning("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: breakpoint already enabled.", breakID, (uint64_t)addr);
            return true;
        }
        else
        {
            if (bp->HardwarePreferred())
            {
                bp->SetHardwareIndex(m_thread_list.EnableHardwareBreakpoint(bp));
                if (bp->IsHardware())
                {
                    bp->SetEnabled(true);
                    return true;
                }
            }

            const nub_size_t break_op_size = bp->ByteSize();
            assert (break_op_size != 0);
            const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (break_op_size);
            if (break_op_size > 0)
            {
                // Save the original opcode by reading it
                if (m_task.ReadMemory(addr, break_op_size, bp->SavedOpcodeBytes()) == break_op_size)
                {
                    // Write a software breakpoint in place of the original opcode
                    if (m_task.WriteMemory(addr, break_op_size, break_op) == break_op_size)
                    {
                        uint8_t verify_break_op[4];
                        if (m_task.ReadMemory(addr, break_op_size, verify_break_op) == break_op_size)
                        {
                            if (memcmp(break_op, verify_break_op, break_op_size) == 0)
                            {
                                bp->SetEnabled(true);
                                // Let the thread list know that a breakpoint has been modified
                                m_thread_list.NotifyBreakpointChanged(bp);
                                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: SUCCESS.", breakID, (uint64_t)addr);
                                return true;
                            }
                            else
                            {
                                DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: breakpoint opcode verification failed.", breakID, (uint64_t)addr);
                            }
                        }
                        else
                        {
                            DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to read memory to verify breakpoint opcode.", breakID, (uint64_t)addr);
                        }
                    }
                    else
                    {
                        DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to write breakpoint opcode to memory.", breakID, (uint64_t)addr);
                    }
                }
                else
                {
                    DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) addr = 0x%8.8llx: unable to read memory at breakpoint address.", breakID, (uint64_t)addr);
                }
            }
            else
            {
                DNBLogError("MachProcess::EnableBreakpoint ( breakID = %d ) no software breakpoint opcode for current architecture.", breakID);
            }
        }
    }
    return false;
}

bool
MachProcess::EnableWatchpoint(nub_watch_t watchID)
{
    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::EnableWatchpoint(watchID = %d)", watchID);
    DNBBreakpoint *wp = m_watchpoints.FindByID (watchID);
    if (wp)
    {
        nub_addr_t addr = wp->Address();
        if (wp->IsEnabled())
        {
            DNBLogWarning("MachProcess::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
            return true;
        }
        else
        {
            // Currently only try and set hardware watchpoints.
            wp->SetHardwareIndex(m_thread_list.EnableHardwareWatchpoint(wp));
            if (wp->IsHardware())
            {
                wp->SetEnabled(true);
                return true;
            }
            // TODO: Add software watchpoints by doing page protection tricks.
        }
    }
    return false;
}

// Called by the exception thread when an exception has been received from
// our process. The exception message is completely filled and the exception
// data has already been copied.
void
MachProcess::ExceptionMessageReceived (const MachException::Message& exceptionMessage)
{
    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);

    if (m_exception_messages.empty())
        m_task.Suspend();

    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachProcess::ExceptionMessageReceived ( )");

    // Use a locker to automatically unlock our mutex in case of exceptions
    // Add the exception to our internal exception stack
    m_exception_messages.push_back(exceptionMessage);
}

void
MachProcess::ExceptionMessageBundleComplete()
{
    // We have a complete bundle of exceptions for our child process.
    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
    DNBLogThreadedIf(LOG_EXCEPTIONS, "%s: %d exception messages.", __PRETTY_FUNCTION__, m_exception_messages.size());
    if (!m_exception_messages.empty())
    {
        // Let all threads recover from stopping and do any clean up based
        // on the previous thread state (if any).
        m_thread_list.ProcessDidStop(this);

        // Let each thread know of any exceptions
        task_t task = m_task.TaskPort();
        size_t i;
        for (i=0; i<m_exception_messages.size(); ++i)
        {
            // Let the thread list figure use the MachProcess to forward all exceptions
            // on down to each thread.
            if (m_exception_messages[i].state.task_port == task)
                m_thread_list.NotifyException(m_exception_messages[i].state);
            if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
                m_exception_messages[i].Dump();
        }

        if (DNBLogCheckLogBit(LOG_THREAD))
            m_thread_list.Dump();

        bool step_more = false;
        if (m_thread_list.ShouldStop(step_more))
        {
            // Wait for the eEventProcessRunningStateChanged event to be reset
            // before changing state to stopped to avoid race condition with
            // very fast start/stops
            struct timespec timeout;
            //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000);   // Wait for 250 ms
            DNBTimer::OffsetTimeOfDay(&timeout, 1, 0);  // Wait for 250 ms
            m_events.WaitForEventsToReset(eEventProcessRunningStateChanged, &timeout);
            SetState(eStateStopped);
        }
        else
        {
            // Resume without checking our current state.
            PrivateResume ();
        }
    }
    else
    {
        DNBLogThreadedIf(LOG_EXCEPTIONS, "%s empty exception messages bundle.", __PRETTY_FUNCTION__, m_exception_messages.size());
    }
}

nub_size_t
MachProcess::CopyImageInfos ( struct DNBExecutableImageInfo **image_infos, bool only_changed)
{
    if (m_image_infos_callback != NULL)
        return m_image_infos_callback(ProcessID(), image_infos, only_changed, m_image_infos_baton);
    return 0;
}

void
MachProcess::SharedLibrariesUpdated ( )
{
    uint32_t event_bits = eEventSharedLibsStateChange;
    // Set the shared library event bit to let clients know of shared library
    // changes
    m_events.SetEvents(event_bits);
    // Wait for the event bit to reset if a reset ACK is requested
    m_events.WaitForResetAck(event_bits);
}

void
MachProcess::AppendSTDOUT (char* s, size_t len)
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (<%d> %s) ...", __FUNCTION__, len, s);
    PTHREAD_MUTEX_LOCKER (locker, m_stdio_mutex);
    m_stdout_data.append(s, len);
    m_events.SetEvents(eEventStdioAvailable);

    // Wait for the event bit to reset if a reset ACK is requested
    m_events.WaitForResetAck(eEventStdioAvailable);
}

size_t
MachProcess::GetAvailableSTDOUT (char *buf, size_t buf_size)
{
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size);
    PTHREAD_MUTEX_LOCKER (locker, m_stdio_mutex);
    size_t bytes_available = m_stdout_data.size();
    if (bytes_available > 0)
    {
        if (bytes_available > buf_size)
        {
            memcpy(buf, m_stdout_data.data(), buf_size);
            m_stdout_data.erase(0, buf_size);
            bytes_available = buf_size;
        }
        else
        {
            memcpy(buf, m_stdout_data.data(), bytes_available);
            m_stdout_data.clear();
        }
    }
    return bytes_available;
}

nub_addr_t
MachProcess::GetDYLDAllImageInfosAddress ()
{
    DNBError err;
    return m_task.GetDYLDAllImageInfosAddress(err);
}

size_t
MachProcess::GetAvailableSTDERR (char *buf, size_t buf_size)
{
    return 0;
}

void *
MachProcess::STDIOThread(void *arg)
{
    MachProcess *proc = (MachProcess*) arg;
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( arg = %p ) thread starting...", __FUNCTION__, arg);

    // We start use a base and more options so we can control if we
    // are currently using a timeout on the mach_msg. We do this to get a
    // bunch of related exceptions on our exception port so we can process
    // then together. When we have multiple threads, we can get an exception
    // per thread and they will come in consecutively. The main thread loop
    // will start by calling mach_msg to without having the MACH_RCV_TIMEOUT
    // flag set in the options, so we will wait forever for an exception on
    // our exception port. After we get one exception, we then will use the
    // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
    // exceptions for our process. After we have received the last pending
    // exception, we will get a timeout which enables us to then notify
    // our main thread that we have an exception bundle avaiable. We then wait
    // for the main thread to tell this exception thread to start trying to get
    // exceptions messages again and we start again with a mach_msg read with
    // infinite timeout.
    DNBError err;
    int stdout_fd = proc->GetStdoutFileDescriptor();
    int stderr_fd = proc->GetStderrFileDescriptor();
    if (stdout_fd == stderr_fd)
        stderr_fd = -1;

    while (stdout_fd >= 0 || stderr_fd >= 0)
    {
        ::pthread_testcancel ();

        fd_set read_fds;
        FD_ZERO (&read_fds);
        if (stdout_fd >= 0)
            FD_SET (stdout_fd, &read_fds);
        if (stderr_fd >= 0)
            FD_SET (stderr_fd, &read_fds);
        int nfds = std::max<int>(stdout_fd, stderr_fd) + 1;

        int num_set_fds = select (nfds, &read_fds, NULL, NULL, NULL);
        DNBLogThreadedIf(LOG_PROCESS, "select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds);

        if (num_set_fds < 0)
        {
            int select_errno = errno;
            if (DNBLogCheckLogBit(LOG_PROCESS))
            {
                err.SetError (select_errno, DNBError::POSIX);
                err.LogThreadedIfError("select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds);
            }

            switch (select_errno)
            {
            case EAGAIN:    // The kernel was (perhaps temporarily) unable to allocate the requested number of file descriptors, or we have non-blocking IO
                break;
            case EBADF:     // One of the descriptor sets specified an invalid descriptor.
                return NULL;
                break;
            case EINTR:     // A signal was delivered before the time limit expired and before any of the selected events occurred.
            case EINVAL:    // The specified time limit is invalid. One of its components is negative or too large.
            default:        // Other unknown error
                break;
            }
        }
        else if (num_set_fds == 0)
        {
        }
        else
        {
            char s[1024];
            s[sizeof(s)-1] = '\0';  // Ensure we have NULL termination
            int bytes_read = 0;
            if (stdout_fd >= 0 && FD_ISSET (stdout_fd, &read_fds))
            {
                do
                {
                    bytes_read = ::read (stdout_fd, s, sizeof(s)-1);
                    if (bytes_read < 0)
                    {
                        int read_errno = errno;
                        DNBLogThreadedIf(LOG_PROCESS, "read (stdout_fd, ) => %d   errno: %d (%s)", bytes_read, read_errno, strerror(read_errno));
                    }
                    else if (bytes_read == 0)
                    {
                        // EOF...
                        DNBLogThreadedIf(LOG_PROCESS, "read (stdout_fd, ) => %d  (reached EOF for child STDOUT)", bytes_read);
                        stdout_fd = -1;
                    }
                    else if (bytes_read > 0)
                    {
                        proc->AppendSTDOUT(s, bytes_read);
                    }

                } while (bytes_read > 0);
            }

            if (stderr_fd >= 0 && FD_ISSET (stderr_fd, &read_fds))
            {
                do
                {
                    bytes_read = ::read (stderr_fd, s, sizeof(s)-1);
                    if (bytes_read < 0)
                    {
                        int read_errno = errno;
                        DNBLogThreadedIf(LOG_PROCESS, "read (stderr_fd, ) => %d   errno: %d (%s)", bytes_read, read_errno, strerror(read_errno));
                    }
                    else if (bytes_read == 0)
                    {
                        // EOF...
                        DNBLogThreadedIf(LOG_PROCESS, "read (stderr_fd, ) => %d  (reached EOF for child STDERR)", bytes_read);
                        stderr_fd = -1;
                    }
                    else if (bytes_read > 0)
                    {
                        proc->AppendSTDOUT(s, bytes_read);
                    }

                } while (bytes_read > 0);
            }
        }
    }
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (%p): thread exiting...", __FUNCTION__, arg);
    return NULL;
}

pid_t
MachProcess::AttachForDebug (pid_t pid, char *err_str, size_t err_len)
{
    // Clear out and clean up from any current state
    Clear();
    if (pid != 0)
    {
        DNBError err;
        // Make sure the process exists...
        if (::getpgid (pid) < 0)
        {
            err.SetErrorToErrno();
            const char *err_cstr = err.AsString();
            ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "No such process");
            return INVALID_NUB_PROCESS;
        }

        SetState(eStateAttaching);
        m_pid = pid;
        // Let ourselves know we are going to be using SBS if the correct flag bit is set...
#if defined (__arm__)
        if (IsSBProcess(pid))
            m_flags |= eMachProcessFlagsUsingSBS;
#endif
        if (!m_task.StartExceptionThread(err))
        {
            const char *err_cstr = err.AsString();
            ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "unable to start the exception thread");
            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
            m_pid = INVALID_NUB_PROCESS;
            return INVALID_NUB_PROCESS;
        }

        errno = 0;
        if (::ptrace (PT_ATTACHEXC, pid, 0, 0))
            err.SetError(errno);
        else
            err.Clear();

        if (err.Success())
        {
            m_flags |= eMachProcessFlagsAttached;
            // Sleep a bit to let the exception get received and set our process status
            // to stopped.
            ::usleep(250000);
            DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", pid);
            return m_pid;
        }
        else
        {
            ::snprintf (err_str, err_len, "%s", err.AsString());
            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
        }
    }
    return INVALID_NUB_PROCESS;
}

// Do the process specific setup for attach.  If this returns NULL, then there's no
// platform specific stuff to be done to wait for the attach.  If you get non-null,
// pass that token to the CheckForProcess method, and then to CleanupAfterAttach.

//  Call PrepareForAttach before attaching to a process that has not yet launched
// This returns a token that can be passed to CheckForProcess, and to CleanupAfterAttach.
// You should call CleanupAfterAttach to free the token, and do whatever other
// cleanup seems good.

const void *
MachProcess::PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str)
{
#if defined (__arm__)
    // Tell SpringBoard to halt the next launch of this application on startup.

    if (!waitfor)
        return NULL;

    const char *app_ext = strstr(path, ".app");
    if (app_ext == NULL)
    {
        DNBLogThreadedIf(LOG_PROCESS, "%s: path '%s' doesn't contain .app, we can't tell springboard to wait for launch...", path);
        return NULL;
    }

    if (launch_flavor != eLaunchFlavorSpringBoard
        && launch_flavor != eLaunchFlavorDefault)
        return NULL;

    std::string app_bundle_path(path, app_ext + strlen(".app"));

    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path.c_str (), err_str);
    std::string bundleIDStr;
    CFString::UTF8(bundleIDCFStr, bundleIDStr);
    DNBLogThreadedIf(LOG_PROCESS, "CopyBundleIDForPath (%s, err_str) returned @\"%s\"", app_bundle_path.c_str (), bundleIDStr.c_str());

    if (bundleIDCFStr == NULL)
    {
        return NULL;
    }

    SBSApplicationLaunchError sbs_error = 0;

    const char *stdout_err = "/dev/null";
    CFString stdio_path;
    stdio_path.SetFileSystemRepresentation (stdout_err);

    DNBLogThreadedIf(LOG_PROCESS, "SBSLaunchApplicationForDebugging ( @\"%s\" , NULL, NULL, NULL, @\"%s\", @\"%s\", SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger )", bundleIDStr.c_str(), stdout_err, stdout_err);
    sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
                                                  (CFURLRef)NULL,         // openURL
                                                  NULL, // launch_argv.get(),
                                                  NULL, // launch_envp.get(),  // CFDictionaryRef environment
                                                  stdio_path.get(),
                                                  stdio_path.get(),
                                                  SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger);

    if (sbs_error != SBSApplicationLaunchErrorSuccess)
    {
        err_str.SetError(sbs_error, DNBError::SpringBoard);
        return NULL;
    }

    DNBLogThreadedIf(LOG_PROCESS, "Successfully set DebugOnNextLaunch.");
    return bundleIDCFStr;
# else
  return NULL;
#endif
}

// Pass in the token you got from PrepareForAttach.  If there is a process
// for that token, then the pid will be returned, otherwise INVALID_NUB_PROCESS
// will be returned.

nub_process_t
MachProcess::CheckForProcess (const void *attach_token)
{
    if (attach_token == NULL)
        return INVALID_NUB_PROCESS;

#if defined (__arm__)
    CFStringRef bundleIDCFStr = (CFStringRef) attach_token;
    Boolean got_it;
    nub_process_t attach_pid;
    got_it = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &attach_pid);
    if (got_it)
        return attach_pid;
    else
        return INVALID_NUB_PROCESS;
#endif
    return INVALID_NUB_PROCESS;
}

// Call this to clean up after you have either attached or given up on the attach.
// Pass true for success if you have attached, false if you have not.
// The token will also be freed at this point, so you can't use it after calling
// this method.

void
MachProcess::CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str)
{
#if defined (__arm__)
    if (attach_token == NULL)
        return;

    // Tell SpringBoard to cancel the debug on next launch of this application
    // if we failed to attach
    if (!success)
    {
        SBSApplicationLaunchError sbs_error = 0;
        CFStringRef bundleIDCFStr = (CFStringRef) attach_token;

        sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
                                                      (CFURLRef)NULL,
                                                      NULL,
                                                      NULL,
                                                      NULL,
                                                      NULL,
                                                      SBSApplicationCancelDebugOnNextLaunch);

        if (sbs_error != SBSApplicationLaunchErrorSuccess)
        {
            err_str.SetError(sbs_error, DNBError::SpringBoard);
            return;
        }
    }

    CFRelease((CFStringRef) attach_token);
#endif
}

pid_t
MachProcess::LaunchForDebug
(
    const char *path,
    char const *argv[],
    char const *envp[],
    const char *working_directory, // NULL => dont' change, non-NULL => set working directory for inferior to this
    const char *stdin_path,
    const char *stdout_path,
    const char *stderr_path,
    bool no_stdio,
    nub_launch_flavor_t launch_flavor,
    int disable_aslr,
    DNBError &launch_err
)
{
    // Clear out and clean up from any current state
    Clear();

    DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d )", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr);

    // Fork a child process for debugging
    SetState(eStateLaunching);

    switch (launch_flavor)
    {
    case eLaunchFlavorForkExec:
        m_pid = MachProcess::ForkChildForPTraceDebugging (path, argv, envp, this, launch_err);
        break;

    case eLaunchFlavorPosixSpawn:
        m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, 
                                                                DNBArchProtocol::GetArchitecture (),
                                                                argv, 
                                                                envp, 
                                                                working_directory,
                                                                stdin_path,
                                                                stdout_path,
                                                                stderr_path,
                                                                no_stdio, 
                                                                this, 
                                                                disable_aslr, 
                                                                launch_err);
        break;

#if defined (__arm__)

    case eLaunchFlavorSpringBoard:
        {
            const char *app_ext = strstr(path, ".app");
            if (app_ext != NULL)
            {
                std::string app_bundle_path(path, app_ext + strlen(".app"));
                return SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, launch_err);
            }
        }
        break;

#endif

    default:
        // Invalid  launch
        launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
        return INVALID_NUB_PROCESS;
    }

    if (m_pid == INVALID_NUB_PROCESS)
    {
        // If we don't have a valid process ID and no one has set the error,
        // then return a generic error
        if (launch_err.Success())
            launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
    }
    else
    {
        m_path = path;
        size_t i;
        char const *arg;
        for (i=0; (arg = argv[i]) != NULL; i++)
            m_args.push_back(arg);

        m_task.StartExceptionThread(launch_err);
        if (launch_err.Fail())
        {
            if (launch_err.AsString() == NULL)
                launch_err.SetErrorString("unable to start the exception thread");
            ::ptrace (PT_KILL, m_pid, 0, 0);
            m_pid = INVALID_NUB_PROCESS;
            return INVALID_NUB_PROCESS;
        }

        StartSTDIOThread();

        if (launch_flavor == eLaunchFlavorPosixSpawn)
        {

            SetState (eStateAttaching);
            errno = 0;
            int err = ::ptrace (PT_ATTACHEXC, m_pid, 0, 0);
            if (err == 0)
            {
                m_flags |= eMachProcessFlagsAttached;
                DNBLogThreadedIf(LOG_PROCESS, "successfully spawned pid %d", m_pid);
                launch_err.Clear();
            }
            else
            {
                SetState (eStateExited);
                DNBError ptrace_err(errno, DNBError::POSIX);
                DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to spawned pid %d (err = %i, errno = %i (%s))", m_pid, err, ptrace_err.Error(), ptrace_err.AsString());
                launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
            }
        }
        else
        {
            launch_err.Clear();
        }
    }
    return m_pid;
}

pid_t
MachProcess::PosixSpawnChildForPTraceDebugging
(
    const char *path,
    cpu_type_t cpu_type,
    char const *argv[],
    char const *envp[],
    const char *working_directory,
    const char *stdin_path,
    const char *stdout_path,
    const char *stderr_path,
    bool no_stdio,
    MachProcess* process,
    int disable_aslr,
    DNBError& err
)
{
    posix_spawnattr_t attr;
    short flags;
    DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv=%p, envp=%p, working_dir=%s, stdin=%s, stdout=%s stderr=%s, no-stdio=%i)", 
                     __FUNCTION__, 
                     path, 
                     argv, 
                     envp,
                     working_directory,
                     stdin_path,
                     stdout_path,
                     stderr_path,
                     no_stdio);

    err.SetError( ::posix_spawnattr_init (&attr), DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
        err.LogThreaded("::posix_spawnattr_init ( &attr )");
    if (err.Fail())
        return INVALID_NUB_PROCESS;

    flags = POSIX_SPAWN_START_SUSPENDED;
    if (disable_aslr)
        flags |= _POSIX_SPAWN_DISABLE_ASLR;
    
    err.SetError( ::posix_spawnattr_setflags (&attr, flags), DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
        err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR" : "");
    if (err.Fail())
        return INVALID_NUB_PROCESS;

    // Don't do this on SnowLeopard, _sometimes_ the TASK_BASIC_INFO will fail
    // and we will fail to continue with our process...
    
    // On SnowLeopard we should set "DYLD_NO_PIE" in the inferior environment....
     
#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 (cpu_type != 0)
    {
        size_t ocount = 0;
        err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), DNBError::POSIX);
        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
            err.LogThreaded("::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu_type, ocount);

        if (err.Fail() != 0 || ocount != 1)
            return INVALID_NUB_PROCESS;
    }
#endif

    PseudoTerminal pty;

    posix_spawn_file_actions_t file_actions;
    err.SetError( ::posix_spawn_file_actions_init (&file_actions), DNBError::POSIX);
    int file_actions_valid = err.Success();
    if (!file_actions_valid || DNBLogCheckLogBit(LOG_PROCESS))
        err.LogThreaded("::posix_spawn_file_actions_init ( &file_actions )");
    int pty_error = -1;
    pid_t pid = INVALID_NUB_PROCESS;
    if (file_actions_valid)
    {
        if (stdin_path == NULL && stdout_path == NULL && stderr_path == NULL && !no_stdio)
        {
            pty_error = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY);
            if (pty_error == PseudoTerminal::success)
            {
                stdin_path = stdout_path = stderr_path = pty.SlaveName();
            }
        }

		// if no_stdio, then do open file actions, opening /dev/null.
        if (no_stdio)
        {
            err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDIN_FILENO, "/dev/null", 
                                                              O_RDONLY | O_NOCTTY, 0), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
                err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDIN_FILENO, path=/dev/null)");
            
            err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDOUT_FILENO, "/dev/null", 
                                                              O_WRONLY | O_NOCTTY, 0), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
                err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDOUT_FILENO, path=/dev/null)");
            
            err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDERR_FILENO, "/dev/null", 
                                                              O_RDWR | O_NOCTTY, 0), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
                err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDERR_FILENO, path=/dev/null)");
        }
        else
        {
            if ( stdin_path == NULL)  stdin_path = "/dev/null";
            if (stdout_path == NULL) stdout_path = "/dev/null";
            if (stderr_path == NULL) stderr_path = "/dev/null";
            
            int slave_fd_err = open (stderr_path, O_NOCTTY | O_CREAT | O_RDWR   , 0640);
            int slave_fd_in  = open (stdin_path , O_NOCTTY | O_RDONLY);
            int slave_fd_out = open (stdout_path, O_NOCTTY | O_CREAT | O_WRONLY , 0640);

            err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_err, STDERR_FILENO), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
                err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDERR_FILENO )", slave_fd_err, stderr_path);

            err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_in, STDIN_FILENO), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
                err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDIN_FILENO )", slave_fd_in, stdin_path);

            err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_out, STDOUT_FILENO), DNBError::POSIX);
            if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
                err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDOUT_FILENO )", slave_fd_out, stdout_path);
        }

        // TODO: Verify if we can set the working directory back immediately
        // after the posix_spawnp call without creating a race condition???
        if (working_directory)
            ::chdir (working_directory);
        
        err.SetError( ::posix_spawnp (&pid, path, &file_actions, &attr, (char * const*)argv, (char * const*)envp), DNBError::POSIX);
        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
            err.LogThreaded("::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, &file_actions, &attr, argv, envp);
    }
    else
    {
        // TODO: Verify if we can set the working directory back immediately
        // after the posix_spawnp call without creating a race condition???
        if (working_directory)
            ::chdir (working_directory);
        
        err.SetError( ::posix_spawnp (&pid, path, NULL, &attr, (char * const*)argv, (char * const*)envp), DNBError::POSIX);
        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
            err.LogThreaded("::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, NULL, &attr, argv, envp);
    }

    // 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 (err.Fail())
        pid = INVALID_NUB_PROCESS;

    if (pty_error == 0)
    {
        if (process != NULL)
        {
            int master_fd = pty.ReleaseMasterFD();
            process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
        }
    }
    ::posix_spawnattr_destroy (&attr);

    if (pid != INVALID_NUB_PROCESS)
    {
        cpu_type_t pid_cpu_type = MachProcess::GetCPUTypeForLocalProcess (pid);
        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( ) pid=%i, cpu_type=0x%8.8x", __FUNCTION__, pid, pid_cpu_type);
        if (pid_cpu_type)
            DNBArchProtocol::SetArchitecture (pid_cpu_type);
    }

    if (file_actions_valid)
    {
        DNBError err2;
        err2.SetError( ::posix_spawn_file_actions_destroy (&file_actions), DNBError::POSIX);
        if (err2.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
            err2.LogThreaded("::posix_spawn_file_actions_destroy ( &file_actions )");
    }

    return pid;
}

uint32_t
MachProcess::GetCPUTypeForLocalProcess (pid_t pid)
{
    int mib[CTL_MAXNAME]={0,};
    size_t len = CTL_MAXNAME;
    if (::sysctlnametomib("sysctl.proc_cputype", mib, &len)) 
        return 0;

    mib[len] = pid;
    len++;
            
    cpu_type_t cpu;
    size_t cpu_len = sizeof(cpu);
    if (::sysctl (mib, len, &cpu, &cpu_len, 0, 0))
        cpu = 0;
    return cpu;
}

pid_t
MachProcess::ForkChildForPTraceDebugging
(
    const char *path,
    char const *argv[],
    char const *envp[],
    MachProcess* process,
    DNBError& launch_err
)
{
    PseudoTerminal::Error pty_error = PseudoTerminal::success;

    // Use a fork that ties the child process's stdin/out/err to a pseudo
    // terminal so we can read it in our MachProcess::STDIOThread
    // as unbuffered io.
    PseudoTerminal pty;
    pid_t pid = pty.Fork(pty_error);

    if (pid < 0)
    {
        //--------------------------------------------------------------
        // Error during fork.
        //--------------------------------------------------------------
        return pid;
    }
    else if (pid == 0)
    {
        //--------------------------------------------------------------
        // Child process
        //--------------------------------------------------------------
        ::ptrace (PT_TRACE_ME, 0, 0, 0);    // Debug this process
        ::ptrace (PT_SIGEXC, 0, 0, 0);    // Get BSD signals as mach exceptions

        // If our parent is setgid, lets make sure we don't inherit those
        // extra powers due to nepotism.
        ::setgid (getgid ());

        // Let the child have its own process group. We need to execute
        // this call in both the child and parent to avoid a race condition
        // between the two processes.
        ::setpgid (0, 0);    // Set the child process group to match its pid

        // Sleep a bit to before the exec call
        ::sleep (1);

        // Turn this process into
        ::execv (path, (char * const *)argv);
        // Exit with error code. Child process should have taken
        // over in above exec call and if the exec fails it will
        // exit the child process below.
        ::exit (127);
    }
    else
    {
        //--------------------------------------------------------------
        // Parent process
        //--------------------------------------------------------------
        // Let the child have its own process group. We need to execute
        // this call in both the child and parent to avoid a race condition
        // between the two processes.
        ::setpgid (pid, pid);    // Set the child process group to match its pid

        if (process != NULL)
        {
            // Release our master pty file descriptor so the pty class doesn't
            // close it and so we can continue to use it in our STDIO thread
            int master_fd = pty.ReleaseMasterFD();
            process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
        }
    }
    return pid;
}

#if defined (__arm__)

pid_t
MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err)
{
    // Clear out and clean up from any current state
    Clear();

    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);

    // Fork a child process for debugging
    SetState(eStateLaunching);
    m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio, this, launch_err);
    if (m_pid != 0)
    {
        m_flags |= eMachProcessFlagsUsingSBS;
        m_path = path;
        size_t i;
        char const *arg;
        for (i=0; (arg = argv[i]) != NULL; i++)
            m_args.push_back(arg);
        m_task.StartExceptionThread(launch_err);
        
        if (launch_err.Fail())
        {
            if (launch_err.AsString() == NULL)
                launch_err.SetErrorString("unable to start the exception thread");
            ::ptrace (PT_KILL, m_pid, 0, 0);
            m_pid = INVALID_NUB_PROCESS;
            return INVALID_NUB_PROCESS;
        }

        StartSTDIOThread();
        SetState (eStateAttaching);
        int err = ::ptrace (PT_ATTACHEXC, m_pid, 0, 0);
        if (err == 0)
        {
            m_flags |= eMachProcessFlagsAttached;
            DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", m_pid);
        }
        else
        {
            SetState (eStateExited);
            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", m_pid);
        }
    }
    return m_pid;
}

#include <servers/bootstrap.h>

// This returns a CFRetained pointer to the Bundle ID for app_bundle_path,
// or NULL if there was some problem getting the bundle id.
static CFStringRef
CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str)
{
    CFBundle bundle(app_bundle_path);
    CFStringRef bundleIDCFStr = bundle.GetIdentifier();
    std::string bundleID;
    if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL)
    {
        struct stat app_bundle_stat;
        char err_msg[PATH_MAX];

        if (::stat (app_bundle_path, &app_bundle_stat) < 0)
        {
            err_str.SetError(errno, DNBError::POSIX);
            snprintf(err_msg, sizeof(err_msg), "%s: \"%s\"", err_str.AsString(), app_bundle_path);
            err_str.SetErrorString(err_msg);
            DNBLogThreadedIf(LOG_PROCESS, "%s() error: %s", __FUNCTION__, err_msg);
        }
        else
        {
            err_str.SetError(-1, DNBError::Generic);
            snprintf(err_msg, sizeof(err_msg), "failed to extract CFBundleIdentifier from %s", app_bundle_path);
            err_str.SetErrorString(err_msg);
            DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to extract CFBundleIdentifier from '%s'", __FUNCTION__, app_bundle_path);
        }
        return NULL;
    }

    DNBLogThreadedIf(LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str());
    CFRetain (bundleIDCFStr);

    return bundleIDCFStr;
}

pid_t
MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err)
{
    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, process);
    CFAllocatorRef alloc = kCFAllocatorDefault;

    if (argv[0] == NULL)
        return INVALID_NUB_PROCESS;

    size_t argc = 0;
    // Count the number of arguments
    while (argv[argc] != NULL)
        argc++;

    // Enumerate the arguments
    size_t first_launch_arg_idx = 1;
    CFReleaser<CFMutableArrayRef> launch_argv;

    if (argv[first_launch_arg_idx])
    {
        size_t launch_argc = argc > 0 ? argc - 1 : 0;
        launch_argv.reset (::CFArrayCreateMutable (alloc, launch_argc, &kCFTypeArrayCallBacks));
        size_t i;
        char const *arg;
        CFString launch_arg;
        for (i=first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL); i++)
        {
            launch_arg.reset(::CFStringCreateWithCString (alloc, arg, kCFStringEncodingUTF8));
            if (launch_arg.get() != NULL)
                CFArrayAppendValue(launch_argv.get(), launch_arg.get());
            else
                break;
        }
    }

    // Next fill in the arguments dictionary.  Note, the envp array is of the form
    // Variable=value but SpringBoard wants a CF dictionary.  So we have to convert
    // this here.

    CFReleaser<CFMutableDictionaryRef> launch_envp;

    if (envp[0])
    {
        launch_envp.reset(::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
        const char *value;
        int name_len;
        CFString name_string, value_string;

        for (int i = 0; envp[i] != NULL; i++)
        {
            value = strstr (envp[i], "=");

            // If the name field is empty or there's no =, skip it.  Somebody's messing with us.
            if (value == NULL || value == envp[i])
                continue;

            name_len = value - envp[i];

            // Now move value over the "="
            value++;

            name_string.reset(::CFStringCreateWithBytes(alloc, (const UInt8 *) envp[i], name_len, kCFStringEncodingUTF8, false));
            value_string.reset(::CFStringCreateWithCString(alloc, value, kCFStringEncodingUTF8));
            CFDictionarySetValue (launch_envp.get(), name_string.get(), value_string.get());
        }
    }

    CFString stdio_path;

    PseudoTerminal pty;
    if (!no_stdio)
    {
        PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY);
        if (pty_err == PseudoTerminal::success)
        {
            const char* slave_name = pty.SlaveName();
            DNBLogThreadedIf(LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name);
            if (slave_name && slave_name[0])
            {
                ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO);
                stdio_path.SetFileSystemRepresentation (slave_name);
            }
        }
    }
    
    if (stdio_path.get() == NULL)
    {
        stdio_path.SetFileSystemRepresentation ("/dev/null");
    }

    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path, launch_err);
    if (bundleIDCFStr == NULL)
        return INVALID_NUB_PROCESS;

    std::string bundleID;
    CFString::UTF8(bundleIDCFStr, bundleID);

    CFData argv_data(NULL);

    if (launch_argv.get())
    {
        if (argv_data.Serialize(launch_argv.get(), kCFPropertyListBinaryFormat_v1_0) == NULL)
        {
            DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to serialize launch arg array...", __FUNCTION__);
            return INVALID_NUB_PROCESS;
        }
    }

    DNBLogThreadedIf(LOG_PROCESS, "%s() serialized launch arg array", __FUNCTION__);

    // Find SpringBoard
    SBSApplicationLaunchError sbs_error = 0;
    sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
                                                  (CFURLRef)NULL,         // openURL
                                                  launch_argv.get(),
                                                  launch_envp.get(),  // CFDictionaryRef environment
                                                  stdio_path.get(),
                                                  stdio_path.get(),
                                                  SBSApplicationLaunchWaitForDebugger | SBSApplicationLaunchUnlockDevice);


    launch_err.SetError(sbs_error, DNBError::SpringBoard);

    if (sbs_error == SBSApplicationLaunchErrorSuccess)
    {
        static const useconds_t pid_poll_interval = 200000;
        static const useconds_t pid_poll_timeout = 30000000;

        useconds_t pid_poll_total = 0;

        nub_process_t pid = INVALID_NUB_PROCESS;
        Boolean pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid);
        // Poll until the process is running, as long as we are getting valid responses and the timeout hasn't expired
        // A return PID of 0 means the process is not running, which may be because it hasn't been (asynchronously) started
        // yet, or that it died very quickly (if you weren't using waitForDebugger).
        while (!pid_found && pid_poll_total < pid_poll_timeout)
        {
            usleep (pid_poll_interval);
            pid_poll_total += pid_poll_interval;
            DNBLogThreadedIf(LOG_PROCESS, "%s() polling Springboard for pid for %s...", __FUNCTION__, bundleID.c_str());
            pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid);
        }

        CFRelease (bundleIDCFStr);
        if (pid_found)
        {
            if (process != NULL)
            {
                // Release our master pty file descriptor so the pty class doesn't
                // close it and so we can continue to use it in our STDIO thread
                int master_fd = pty.ReleaseMasterFD();
                process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
            }
            DNBLogThreadedIf(LOG_PROCESS, "%s() => pid = %4.4x", __FUNCTION__, pid);
        }
        else
        {
            DNBLogError("failed to lookup the process ID for CFBundleIdentifier %s.", bundleID.c_str());
        }
        return pid;
    }

    DNBLogError("unable to launch the application with CFBundleIdentifier '%s' sbs_error = %u", bundleID.c_str(), sbs_error);
    return INVALID_NUB_PROCESS;
}

#endif // #if defined (__arm__)


