//===-- DNB.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 3/23/07.
//
//===----------------------------------------------------------------------===//

#include "DNB.h"
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <map>
#include <vector>
#include <libproc.h>

#if defined (__APPLE__)
#include <pthread.h>
#include <sched.h>
#endif

#define TRY_KQUEUE 1

#ifdef TRY_KQUEUE
    #include <sys/event.h>
    #include <sys/time.h>
    #ifdef NOTE_EXIT_DETAIL
        #define USE_KQUEUE
    #endif
#endif

#include "MacOSX/MachProcess.h"
#include "MacOSX/MachTask.h"
#include "MacOSX/Genealogy.h"
#include "MacOSX/ThreadInfo.h"
#include "CFString.h"
#include "DNBLog.h"
#include "DNBDataRef.h"
#include "DNBThreadResumeActions.h"
#include "DNBTimer.h"
#include "CFBundle.h"


typedef std::shared_ptr<MachProcess> MachProcessSP;
typedef std::map<nub_process_t, MachProcessSP> ProcessMap;
typedef ProcessMap::iterator ProcessMapIter;
typedef ProcessMap::const_iterator ProcessMapConstIter;

size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
static size_t GetAllInfosMatchingName (const char *process_name, std::vector<struct kinfo_proc>& matching_proc_infos);

//----------------------------------------------------------------------
// A Thread safe singleton to get a process map pointer.
//
// Returns a pointer to the existing process map, or a pointer to a
// newly created process map if CAN_CREATE is non-zero.
//----------------------------------------------------------------------
static ProcessMap*
GetProcessMap(bool can_create)
{
    static ProcessMap* g_process_map_ptr = NULL;

    if (can_create && g_process_map_ptr == NULL)
    {
        static pthread_mutex_t g_process_map_mutex = PTHREAD_MUTEX_INITIALIZER;
        PTHREAD_MUTEX_LOCKER (locker, &g_process_map_mutex);
        if (g_process_map_ptr == NULL)
            g_process_map_ptr = new ProcessMap;
    }
    return g_process_map_ptr;
}

//----------------------------------------------------------------------
// Add PID to the shared process pointer map.
//
// Return non-zero value if we succeed in adding the process to the map.
// The only time this should fail is if we run out of memory and can't
// allocate a ProcessMap.
//----------------------------------------------------------------------
static nub_bool_t
AddProcessToMap (nub_process_t pid, MachProcessSP& procSP)
{
    ProcessMap* process_map = GetProcessMap(true);
    if (process_map)
    {
        process_map->insert(std::make_pair(pid, procSP));
        return true;
    }
    return false;
}

//----------------------------------------------------------------------
// Remove the shared pointer for PID from the process map.
//
// Returns the number of items removed from the process map.
//----------------------------------------------------------------------
//static size_t
//RemoveProcessFromMap (nub_process_t pid)
//{
//    ProcessMap* process_map = GetProcessMap(false);
//    if (process_map)
//    {
//        return process_map->erase(pid);
//    }
//    return 0;
//}

//----------------------------------------------------------------------
// Get the shared pointer for PID from the existing process map.
//
// Returns true if we successfully find a shared pointer to a
// MachProcess object.
//----------------------------------------------------------------------
static nub_bool_t
GetProcessSP (nub_process_t pid, MachProcessSP& procSP)
{
    ProcessMap* process_map = GetProcessMap(false);
    if (process_map != NULL)
    {
        ProcessMapIter pos = process_map->find(pid);
        if (pos != process_map->end())
        {
            procSP = pos->second;
            return true;
        }
    }
    procSP.reset();
    return false;
}

#ifdef USE_KQUEUE
void *
kqueue_thread (void *arg)
{
    int kq_id = (int) (intptr_t) arg;
    
#if defined (__APPLE__)
    pthread_setname_np ("kqueue thread");
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
    struct sched_param thread_param;
    int thread_sched_policy;
    if (pthread_getschedparam(pthread_self(), &thread_sched_policy, &thread_param) == 0) 
    {
        thread_param.sched_priority = 47;
        pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
    }
#endif
#endif

    struct kevent death_event;
    while (1)
    {        
        int n_events = kevent (kq_id, NULL, 0, &death_event, 1, NULL);
        if (n_events == -1)
        {
            if (errno == EINTR)
                continue;
            else
            {
                DNBLogError ("kqueue failed with error: (%d): %s", errno, strerror(errno));
                return NULL;
            }
        }
        else if (death_event.flags & EV_ERROR)
        {
            int error_no = static_cast<int>(death_event.data);
            const char *error_str = strerror(error_no);
            if (error_str == NULL)
                error_str = "Unknown error";
            DNBLogError ("Failed to initialize kqueue event: (%d): %s", error_no, error_str );
            return NULL;
        }
        else
        {
            int status;
            const pid_t pid = (pid_t)death_event.ident;
            const pid_t child_pid = waitpid (pid, &status, 0);
            
            
            bool exited = false;
            int signal = 0;
            int exit_status = 0;
            if (WIFSTOPPED(status))
            {
                signal = WSTOPSIG(status);
                DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> STOPPED (signal = %i)", child_pid, signal);
            }
            else if (WIFEXITED(status))
            {
                exit_status = WEXITSTATUS(status);
                exited = true;
                DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> EXITED (status = %i)", child_pid, exit_status);
            }
            else if (WIFSIGNALED(status))
            {
                signal = WTERMSIG(status);
                if (child_pid == abs(pid))
                {
                    DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> SIGNALED and EXITED (signal = %i)", child_pid, signal);
                    char exit_info[64];
                    ::snprintf (exit_info, sizeof(exit_info), "Terminated due to signal %i", signal);
                    DNBProcessSetExitInfo (child_pid, exit_info);
                    exited = true;
                    exit_status = INT8_MAX;
                }
                else
                {
                    DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> SIGNALED (signal = %i)", child_pid, signal);
                }
            }

            if (exited)
            {
                if (death_event.data & NOTE_EXIT_MEMORY)
                    DNBProcessSetExitInfo (child_pid, "Terminated due to memory issue");
                else if (death_event.data & NOTE_EXIT_DECRYPTFAIL)
                    DNBProcessSetExitInfo (child_pid, "Terminated due to decrypt failure");
                else if (death_event.data & NOTE_EXIT_CSERROR)
                    DNBProcessSetExitInfo (child_pid, "Terminated due to code signing error");
                
                DNBLogThreadedIf(LOG_PROCESS, "waitpid_process_thread (): setting exit status for pid = %i to %i", child_pid, exit_status);
                DNBProcessSetExitStatus (child_pid, status);
                return NULL;
            }
        }
    }
}

static bool
spawn_kqueue_thread (pid_t pid)
{
    pthread_t thread;
    int kq_id;
    
    kq_id = kqueue();
    if (kq_id == -1)
    {
        DNBLogError ("Could not get kqueue for pid = %i.", pid);
        return false;
    }

    struct kevent reg_event;
    
    EV_SET(&reg_event, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT|NOTE_EXITSTATUS|NOTE_EXIT_DETAIL, 0, NULL);
    // Register the event:
    int result = kevent (kq_id, &reg_event, 1, NULL, 0, NULL);
    if (result != 0)
    {
        DNBLogError ("Failed to register kqueue NOTE_EXIT event for pid %i, error: %d.", pid, result);
        return false;
    }
    
    int ret = ::pthread_create (&thread, NULL, kqueue_thread, (void *)(intptr_t)kq_id);
    
    // pthread_create returns 0 if successful
    if (ret == 0)
    {
        ::pthread_detach (thread);
        return true;
    }
    return false;
}
#endif // #if USE_KQUEUE

static void *
waitpid_thread (void *arg)
{
    const pid_t pid = (pid_t)(intptr_t)arg;
    int status;

#if defined (__APPLE__)
    pthread_setname_np ("waitpid thread");
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
    struct sched_param thread_param;
    int thread_sched_policy;
    if (pthread_getschedparam(pthread_self(), &thread_sched_policy, &thread_param) == 0) 
    {
        thread_param.sched_priority = 47;
        pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
    }
#endif
#endif

    while (1)
    {
        pid_t child_pid = waitpid(pid, &status, 0);
        DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): waitpid (pid = %i, &status, 0) => %i, status = %i, errno = %i", pid, child_pid, status, errno);

        if (child_pid < 0)
        {
            if (errno == EINTR)
                continue;
            break;
        }
        else
        {
            if (WIFSTOPPED(status))
            {
                continue;
            }
            else// if (WIFEXITED(status) || WIFSIGNALED(status))
            {
                DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): setting exit status for pid = %i to %i", child_pid, status);
                DNBProcessSetExitStatus (child_pid, status);
                return NULL;
            }
        }
    }

    // We should never exit as long as our child process is alive, so if we
    // do something else went wrong and we should exit...
    DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): main loop exited, setting exit status to an invalid value (-1) for pid %i", pid);
    DNBProcessSetExitStatus (pid, -1);
    return NULL;
}
static bool
spawn_waitpid_thread (pid_t pid)
{
#ifdef USE_KQUEUE
    bool success = spawn_kqueue_thread (pid);
    if (success)
        return true;
#endif

    pthread_t thread;
    int ret = ::pthread_create (&thread, NULL, waitpid_thread, (void *)(intptr_t)pid);
    // pthread_create returns 0 if successful
    if (ret == 0)
    {
        ::pthread_detach (thread);
        return true;
    }
    return false;
}

nub_process_t
DNBProcessLaunch (const char *path,
                  char const *argv[],
                  const char *envp[],
                  const char *working_directory, // NULL => don't 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,
                  const char *event_data,
                  char *err_str,
                  size_t err_len)
{
    DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %llu) called...",
                     __FUNCTION__, 
                     path, 
                     argv, 
                     envp, 
                     working_directory,
                     stdin_path,
                     stdout_path,
                     stderr_path,
                     no_stdio,
                     launch_flavor, 
                     disable_aslr, 
                     err_str, 
                     (uint64_t)err_len);
    
    if (err_str && err_len > 0)
        err_str[0] = '\0';
    struct stat path_stat;
    if (::stat(path, &path_stat) == -1)
    {
        char stat_error[256];
        ::strerror_r (errno, stat_error, sizeof(stat_error));
        snprintf(err_str, err_len, "%s (%s)", stat_error, path);
        return INVALID_NUB_PROCESS;
    }

    MachProcessSP processSP (new MachProcess);
    if (processSP.get())
    {
        DNBError launch_err;
        pid_t pid = processSP->LaunchForDebug (path, 
                                               argv, 
                                               envp, 
                                               working_directory, 
                                               stdin_path, 
                                               stdout_path, 
                                               stderr_path, 
                                               no_stdio, 
                                               launch_flavor, 
                                               disable_aslr,
                                               event_data,
                                               launch_err);
        if (err_str)
        {
            *err_str = '\0';
            if (launch_err.Fail())
            {
                const char *launch_err_str = launch_err.AsString();
                if (launch_err_str)
                {
                    strncpy(err_str, launch_err_str, err_len-1);
                    err_str[err_len-1] = '\0';  // Make sure the error string is terminated
                }
            }
        }

        DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) new pid is %d...", pid);

        if (pid != INVALID_NUB_PROCESS)
        {
            // Spawn a thread to reap our child inferior process...
            spawn_waitpid_thread (pid);

            if (processSP->Task().TaskPortForProcessID (launch_err) == TASK_NULL)
            {
                // We failed to get the task for our process ID which is bad.
                // Kill our process otherwise it will be stopped at the entry
                // point and get reparented to someone else and never go away.
                DNBLog ("Could not get task port for process, sending SIGKILL and exiting.");
                kill (SIGKILL, pid);

                if (err_str && err_len > 0)
                {
                    if (launch_err.AsString())
                    {
                        ::snprintf (err_str, err_len, "failed to get the task for process %i (%s)", pid, launch_err.AsString());
                    }
                    else
                    {
                        ::snprintf (err_str, err_len, "failed to get the task for process %i", pid);
                    }
                }
            }
            else
            {
                bool res = AddProcessToMap(pid, processSP);
                assert(res && "Couldn't add process to map!");
                return pid;
            }
        }
    }
    return INVALID_NUB_PROCESS;
}

nub_process_t
DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_str, size_t err_len)
{
    if (err_str && err_len > 0)
        err_str[0] = '\0';
    std::vector<struct kinfo_proc> matching_proc_infos;
    size_t num_matching_proc_infos = GetAllInfosMatchingName(name, matching_proc_infos);
    if (num_matching_proc_infos == 0)
    {
        DNBLogError ("error: no processes match '%s'\n", name);
        return INVALID_NUB_PROCESS;
    }
    else if (num_matching_proc_infos > 1)
    {
        DNBLogError ("error: %llu processes match '%s':\n", (uint64_t)num_matching_proc_infos, name);
        size_t i;
        for (i=0; i<num_matching_proc_infos; ++i)
            DNBLogError ("%6u - %s\n", matching_proc_infos[i].kp_proc.p_pid, matching_proc_infos[i].kp_proc.p_comm);
        return INVALID_NUB_PROCESS;
    }
    
    return DNBProcessAttach (matching_proc_infos[0].kp_proc.p_pid, timeout, err_str, err_len);
}

nub_process_t
DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_str, size_t err_len)
{
    if (err_str && err_len > 0)
        err_str[0] = '\0';

    pid_t pid = INVALID_NUB_PROCESS;
    MachProcessSP processSP(new MachProcess);
    if (processSP.get())
    {
        DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...", attach_pid);
        pid = processSP->AttachForDebug (attach_pid, err_str,  err_len);

        if (pid != INVALID_NUB_PROCESS)
        {
            bool res = AddProcessToMap(pid, processSP);
            assert(res && "Couldn't add process to map!");
            spawn_waitpid_thread(pid);
        }
    }

    while (pid != INVALID_NUB_PROCESS)
    {
        // Wait for process to start up and hit entry point
        DNBLogThreadedIf (LOG_PROCESS, 
                          "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE)...",
                          __FUNCTION__, 
                          pid);
        nub_event_t set_events = DNBProcessWaitForEvents (pid,
                                                          eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged,
                                                          true, 
                                                          timeout);

        DNBLogThreadedIf (LOG_PROCESS, 
                          "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE) => 0x%8.8x",
                          __FUNCTION__, 
                          pid, 
                          set_events);

        if (set_events == 0)
        {
            if (err_str && err_len > 0)
                snprintf(err_str, err_len, "operation timed out");
            pid = INVALID_NUB_PROCESS;
        }
        else
        {
            if (set_events & (eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged))
            {
                nub_state_t pid_state = DNBProcessGetState (pid);
                DNBLogThreadedIf (LOG_PROCESS, "%s process %4.4x state changed (eEventProcessStateChanged): %s",
                        __FUNCTION__, pid, DNBStateAsString(pid_state));

                switch (pid_state)
                {
                    default:
                    case eStateInvalid:
                    case eStateUnloaded:
                    case eStateAttaching:
                    case eStateLaunching:
                    case eStateSuspended:
                        break;  // Ignore
                        
                    case eStateRunning:
                    case eStateStepping:
                        // Still waiting to stop at entry point...
                        break;
                        
                    case eStateStopped:
                    case eStateCrashed:
                        return pid;

                    case eStateDetached:
                    case eStateExited:
                        if (err_str && err_len > 0)
                            snprintf(err_str, err_len, "process exited");
                        return INVALID_NUB_PROCESS;
                }
            }

            DNBProcessResetEvents(pid, set_events);
        }
    }

    return INVALID_NUB_PROCESS;
}

size_t
GetAllInfos (std::vector<struct kinfo_proc>& proc_infos)
{
    size_t size = 0;
    int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
    u_int namelen = sizeof(name)/sizeof(int);
    int err;

    // Try to find out how many processes are around so we can
    // size the buffer appropriately.  sysctl's man page specifically suggests
    // this approach, and says it returns a bit larger size than needed to
    // handle any new processes created between then and now.

    err = ::sysctl (name, namelen, NULL, &size, NULL, 0);

    if ((err < 0) && (err != ENOMEM))
    {
        proc_infos.clear();
        perror("sysctl (mib, miblen, NULL, &num_processes, NULL, 0)");
        return 0;
    }


    // Increase the size of the buffer by a few processes in case more have
    // been spawned
    proc_infos.resize (size / sizeof(struct kinfo_proc));
    size = proc_infos.size() * sizeof(struct kinfo_proc);   // Make sure we don't exceed our resize...
    err = ::sysctl (name, namelen, &proc_infos[0], &size, NULL, 0);
    if (err < 0)
    {
        proc_infos.clear();
        return 0;
    }

    // Trim down our array to fit what we actually got back
    proc_infos.resize(size / sizeof(struct kinfo_proc));
    return proc_infos.size();
}

static size_t
GetAllInfosMatchingName(const char *full_process_name, std::vector<struct kinfo_proc>& matching_proc_infos)
{

    matching_proc_infos.clear();
    if (full_process_name && full_process_name[0])
    {
        // We only get the process name, not the full path, from the proc_info.  So just take the
        // base name of the process name...
        const char *process_name;
        process_name = strrchr (full_process_name, '/');
        if (process_name == NULL)
            process_name = full_process_name;
        else
            process_name++;

        const size_t process_name_len = strlen(process_name);
        std::vector<struct kinfo_proc> proc_infos;
        const size_t num_proc_infos = GetAllInfos(proc_infos);
        if (num_proc_infos > 0)
        {
            uint32_t i;
            for (i=0; i<num_proc_infos; i++)
            {
                // Skip zombie processes and processes with unset status
                if (proc_infos[i].kp_proc.p_stat == 0 || proc_infos[i].kp_proc.p_stat == SZOMB)
                    continue;

                // Check for process by name. We only check the first MAXCOMLEN
                // chars as that is all that kp_proc.p_comm holds.
                
                if (::strncasecmp(process_name, proc_infos[i].kp_proc.p_comm, MAXCOMLEN) == 0)
                {
                    if (process_name_len > MAXCOMLEN)
                    {
                        // We found a matching process name whose first MAXCOMLEN
                        // characters match, but there is more to the name than
                        // this. We need to get the full process name.  Use proc_pidpath, which will get
                        // us the full path to the executed process.

                        char proc_path_buf[PATH_MAX];
                        
                        int return_val = proc_pidpath (proc_infos[i].kp_proc.p_pid, proc_path_buf, PATH_MAX);
                        if (return_val > 0)
                        {
                            // Okay, now search backwards from that to see if there is a
                            // slash in the name.  Note, even though we got all the args we don't care
                            // because the list data is just a bunch of concatenated null terminated strings
                            // so strrchr will start from the end of argv0.
                            
                            const char *argv_basename = strrchr(proc_path_buf, '/');
                            if (argv_basename)
                            {
                                // Skip the '/'
                                ++argv_basename;
                            }
                            else
                            {
                                // We didn't find a directory delimiter in the process argv[0], just use what was in there
                                argv_basename = proc_path_buf;
                            }

                            if (argv_basename)
                            {
                                if (::strncasecmp(process_name, argv_basename, PATH_MAX) == 0)
                                {
                                    matching_proc_infos.push_back(proc_infos[i]);
                                }
                            }
                        }
                    }
                    else
                    {
                        // We found a matching process, add it to our list
                        matching_proc_infos.push_back(proc_infos[i]);
                    }
                }
            }
        }
    }
    // return the newly added matches.
    return matching_proc_infos.size();
}

nub_process_t
DNBProcessAttachWait (const char *waitfor_process_name, 
                      nub_launch_flavor_t launch_flavor,
                      bool ignore_existing,
                      struct timespec *timeout_abstime, 
                      useconds_t waitfor_interval,
                      char *err_str, 
                      size_t err_len,
                      DNBShouldCancelCallback should_cancel_callback,
                      void *callback_data)
{
    DNBError prepare_error;
    std::vector<struct kinfo_proc> exclude_proc_infos;
    size_t num_exclude_proc_infos;

    // If the PrepareForAttach returns a valid token, use  MachProcess to check
    // for the process, otherwise scan the process table.

    const void *attach_token = MachProcess::PrepareForAttach (waitfor_process_name, launch_flavor, true, prepare_error);

    if (prepare_error.Fail())
    {
        DNBLogError ("Error in PrepareForAttach: %s", prepare_error.AsString());
        return INVALID_NUB_PROCESS;
    }

    if (attach_token == NULL)
    {
        if (ignore_existing)
            num_exclude_proc_infos = GetAllInfosMatchingName (waitfor_process_name, exclude_proc_infos);
        else
            num_exclude_proc_infos = 0;
    }

    DNBLogThreadedIf (LOG_PROCESS, "Waiting for '%s' to appear...\n", waitfor_process_name);

    // Loop and try to find the process by name
    nub_process_t waitfor_pid = INVALID_NUB_PROCESS;

    while (waitfor_pid == INVALID_NUB_PROCESS)
    {
        if (attach_token != NULL)
        {
            nub_process_t pid;
            pid = MachProcess::CheckForProcess(attach_token);
            if (pid != INVALID_NUB_PROCESS)
            {
                waitfor_pid = pid;
                break;
            }
        }
        else
        {

            // Get the current process list, and check for matches that
            // aren't in our original list. If anyone wants to attach
            // to an existing process by name, they should do it with
            // --attach=PROCNAME. Else we will wait for the first matching
            // process that wasn't in our exclusion list.
            std::vector<struct kinfo_proc> proc_infos;
            const size_t num_proc_infos = GetAllInfosMatchingName (waitfor_process_name, proc_infos);
            for (size_t i=0; i<num_proc_infos; i++)
            {
                nub_process_t curr_pid = proc_infos[i].kp_proc.p_pid;
                for (size_t j=0; j<num_exclude_proc_infos; j++)
                {
                    if (curr_pid == exclude_proc_infos[j].kp_proc.p_pid)
                    {
                        // This process was in our exclusion list, don't use it.
                        curr_pid = INVALID_NUB_PROCESS;
                        break;
                    }
                }

                // If we didn't find CURR_PID in our exclusion list, then use it.
                if (curr_pid != INVALID_NUB_PROCESS)
                {
                    // We found our process!
                    waitfor_pid = curr_pid;
                    break;
                }
            }
        }

        // If we haven't found our process yet, check for a timeout
        // and then sleep for a bit until we poll again.
        if (waitfor_pid == INVALID_NUB_PROCESS)
        {
            if (timeout_abstime != NULL)
            {
                // Check to see if we have a waitfor-duration option that
                // has timed out?
                if (DNBTimer::TimeOfDayLaterThan(*timeout_abstime))
                {
                    if (err_str && err_len > 0)
                        snprintf(err_str, err_len, "operation timed out");
                    DNBLogError ("error: waiting for process '%s' timed out.\n", waitfor_process_name);
                    return INVALID_NUB_PROCESS;
                }
            }

            // Call the should cancel callback as well...

            if (should_cancel_callback != NULL
                && should_cancel_callback (callback_data))
            {
                DNBLogThreadedIf (LOG_PROCESS, "DNBProcessAttachWait cancelled by should_cancel callback.");
                waitfor_pid = INVALID_NUB_PROCESS;
                break;
            }

            ::usleep (waitfor_interval);    // Sleep for WAITFOR_INTERVAL, then poll again
        }
    }

    if (waitfor_pid != INVALID_NUB_PROCESS)
    {
        DNBLogThreadedIf (LOG_PROCESS, "Attaching to %s with pid %i...\n", waitfor_process_name, waitfor_pid);
        waitfor_pid = DNBProcessAttach (waitfor_pid, timeout_abstime, err_str, err_len);
    }

    bool success = waitfor_pid != INVALID_NUB_PROCESS;
    MachProcess::CleanupAfterAttach (attach_token, success, prepare_error);

    return waitfor_pid;
}

nub_bool_t
DNBProcessDetach (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        const bool remove = true;
        DNBLogThreaded("Disabling breakpoints and watchpoints, and detaching from %d.", pid);
        procSP->DisableAllBreakpoints(remove);
        procSP->DisableAllWatchpoints (remove);
        return procSP->Detach();
    }
    return false;
}

nub_bool_t
DNBProcessKill (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->Kill ();
    }
    return false;
}

nub_bool_t
DNBProcessSignal (nub_process_t pid, int signal)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->Signal (signal);
    }
    return false;
}


nub_bool_t
DNBProcessInterrupt(nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Interrupt();
    return false;
}

nub_bool_t
DNBProcessSendEvent (nub_process_t pid, const char *event)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        // FIXME: Do something with the error...
        DNBError send_error;
        return procSP->SendEvent (event, send_error);
    }
    return false;
}


nub_bool_t
DNBProcessIsAlive (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return MachTask::IsValid (procSP->Task().TaskPort());
    }
    return eStateInvalid;
}

//----------------------------------------------------------------------
// Process and Thread state information
//----------------------------------------------------------------------
nub_state_t
DNBProcessGetState (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetState();
    }
    return eStateInvalid;
}

//----------------------------------------------------------------------
// Process and Thread state information
//----------------------------------------------------------------------
nub_bool_t
DNBProcessGetExitStatus (nub_process_t pid, int* status)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetExitStatus(status);
    }
    return false;
}

nub_bool_t
DNBProcessSetExitStatus (nub_process_t pid, int status)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SetExitStatus(status);
        return true;
    }
    return false;
}

const char *
DNBProcessGetExitInfo (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetExitInfo();
    }
    return NULL;
}

nub_bool_t
DNBProcessSetExitInfo (nub_process_t pid, const char *info)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SetExitInfo(info);
        return true;
    }
    return false;
}

const char *
DNBThreadGetName (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->ThreadGetName(tid);
    return NULL;
}


nub_bool_t
DNBThreadGetIdentifierInfo (nub_process_t pid, nub_thread_t tid, thread_identifier_info_data_t *ident_info)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetThreadList().GetIdentifierInfo(tid, ident_info);
    return false;
}

nub_state_t
DNBThreadGetState (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->ThreadGetState(tid);
    }
    return eStateInvalid;
}

const char *
DNBStateAsString(nub_state_t state)
{
    switch (state)
    {
    case eStateInvalid:     return "Invalid";
    case eStateUnloaded:    return "Unloaded";
    case eStateAttaching:   return "Attaching";
    case eStateLaunching:   return "Launching";
    case eStateStopped:     return "Stopped";
    case eStateRunning:     return "Running";
    case eStateStepping:    return "Stepping";
    case eStateCrashed:     return "Crashed";
    case eStateDetached:    return "Detached";
    case eStateExited:      return "Exited";
    case eStateSuspended:   return "Suspended";
    }
    return "nub_state_t ???";
}

Genealogy::ThreadActivitySP
DNBGetGenealogyInfoForThread (nub_process_t pid, nub_thread_t tid, bool &timed_out)
{
    Genealogy::ThreadActivitySP thread_activity_sp;
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        thread_activity_sp = procSP->GetGenealogyInfoForThread (tid, timed_out);
    return thread_activity_sp;
}

Genealogy::ProcessExecutableInfoSP
DNBGetGenealogyImageInfo (nub_process_t pid, size_t idx)
{
    Genealogy::ProcessExecutableInfoSP image_info_sp;
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        image_info_sp = procSP->GetGenealogyImageInfo (idx);
    }
    return image_info_sp;
}

ThreadInfo::QoS
DNBGetRequestedQoSForThread (nub_process_t pid, nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetRequestedQoS (tid, tsd, dti_qos_class_index);
    }
    return ThreadInfo::QoS();
}

nub_addr_t
DNBGetPThreadT (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetPThreadT (tid);
    }
    return INVALID_NUB_ADDRESS;
}

nub_addr_t
DNBGetDispatchQueueT (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetDispatchQueueT (tid);
    }
    return INVALID_NUB_ADDRESS;
}

nub_addr_t
DNBGetTSDAddressForThread (nub_process_t pid, nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetTSDAddressForThread (tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
    }
    return INVALID_NUB_ADDRESS;
}

JSONGenerator::ObjectSP 
DNBGetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
    }
    return JSONGenerator::ObjectSP();
}



const char *
DNBProcessGetExecutablePath (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->Path();
    }
    return NULL;
}

nub_size_t
DNBProcessGetArgumentCount (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->ArgumentCount();
    }
    return 0;
}

const char *
DNBProcessGetArgumentAtIndex (nub_process_t pid, nub_size_t idx)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->ArgumentAtIndex (idx);
    }
    return NULL;
}


//----------------------------------------------------------------------
// Execution control
//----------------------------------------------------------------------
nub_bool_t
DNBProcessResume (nub_process_t pid, const DNBThreadResumeAction *actions, size_t num_actions)
{
    DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        DNBThreadResumeActions thread_actions (actions, num_actions);

        // Below we add a default thread plan just in case one wasn't
        // provided so all threads always know what they were supposed to do
        if (thread_actions.IsEmpty())
        {
            // No thread plans were given, so the default it to run all threads
            thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
        }
        else
        {
            // Some thread plans were given which means anything that wasn't
            // specified should remain stopped.
            thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
        }
        return procSP->Resume (thread_actions);
    }
    return false;
}

nub_bool_t
DNBProcessHalt (nub_process_t pid)
{
    DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Signal (SIGSTOP);
    return false;
}
//
//nub_bool_t
//DNBThreadResume (nub_process_t pid, nub_thread_t tid, nub_bool_t step)
//{
//    DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u)", __FUNCTION__, pid, tid, (uint32_t)step);
//    MachProcessSP procSP;
//    if (GetProcessSP (pid, procSP))
//    {
//        return procSP->Resume(tid, step, 0);
//    }
//    return false;
//}
//
//nub_bool_t
//DNBThreadResumeWithSignal (nub_process_t pid, nub_thread_t tid, nub_bool_t step, int signal)
//{
//    DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u, signal = %i)", __FUNCTION__, pid, tid, (uint32_t)step, signal);
//    MachProcessSP procSP;
//    if (GetProcessSP (pid, procSP))
//    {
//        return procSP->Resume(tid, step, signal);
//    }
//    return false;
//}

nub_event_t
DNBProcessWaitForEvents (nub_process_t pid, nub_event_t event_mask, bool wait_for_set, struct timespec* timeout)
{
    nub_event_t result = 0;
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        if (wait_for_set)
            result = procSP->Events().WaitForSetEvents(event_mask, timeout);
        else
            result = procSP->Events().WaitForEventsToReset(event_mask, timeout);
    }
    return result;
}

void
DNBProcessResetEvents (nub_process_t pid, nub_event_t event_mask)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        procSP->Events().ResetEvents(event_mask);
}

// Breakpoints
nub_bool_t
DNBBreakpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, nub_bool_t hardware)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->CreateBreakpoint(addr, size, hardware) != NULL;
    return false;
}

nub_bool_t
DNBBreakpointClear (nub_process_t pid, nub_addr_t addr)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->DisableBreakpoint(addr, true);
    return false; // Failed
}


//----------------------------------------------------------------------
// Watchpoints
//----------------------------------------------------------------------
nub_bool_t
DNBWatchpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, uint32_t watch_flags, nub_bool_t hardware)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->CreateWatchpoint(addr, size, watch_flags, hardware) != NULL;
    return false;
}

nub_bool_t
DNBWatchpointClear (nub_process_t pid, nub_addr_t addr)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->DisableWatchpoint(addr, true);
    return false; // Failed
}

//----------------------------------------------------------------------
// Return the number of supported hardware watchpoints.
//----------------------------------------------------------------------
uint32_t
DNBWatchpointGetNumSupportedHWP (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetNumSupportedHardwareWatchpoints();
    return 0;
}

//----------------------------------------------------------------------
// Read memory in the address space of process PID. This call will take
// care of setting and restoring permissions and breaking up the memory
// read into multiple chunks as required.
//
// RETURNS: number of bytes actually read
//----------------------------------------------------------------------
nub_size_t
DNBProcessMemoryRead (nub_process_t pid, nub_addr_t addr, nub_size_t size, void *buf)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->ReadMemory(addr, size, buf);
    return 0;
}

uint64_t
DNBProcessMemoryReadInteger (nub_process_t pid, nub_addr_t addr, nub_size_t integer_size, uint64_t fail_value)
{
    union Integers
    {
        uint8_t     u8;
        uint16_t    u16;
        uint32_t    u32;
        uint64_t    u64;
    };

    if (integer_size <= sizeof(uint64_t))
    {
        Integers ints;
        if (DNBProcessMemoryRead(pid, addr, integer_size, &ints) == integer_size)
        {
            switch (integer_size)
            {
                case 1: return ints.u8;
                case 2: return ints.u16;
                case 3: return ints.u32 & 0xffffffu;
                case 4: return ints.u32;
                case 5: return ints.u32 & 0x000000ffffffffffull;
                case 6: return ints.u32 & 0x0000ffffffffffffull;
                case 7: return ints.u32 & 0x00ffffffffffffffull;
                case 8: return ints.u64;
            }
        }
    }
    return fail_value;

}

nub_addr_t
DNBProcessMemoryReadPointer (nub_process_t pid, nub_addr_t addr)
{
    cpu_type_t cputype = DNBProcessGetCPUType (pid);
    if (cputype)
    {
        const nub_size_t pointer_size = (cputype & CPU_ARCH_ABI64) ? 8 : 4;
        return DNBProcessMemoryReadInteger(pid, addr, pointer_size, 0);
    }
    return 0;

}

std::string
DNBProcessMemoryReadCString (nub_process_t pid, nub_addr_t addr)
{
    std::string cstr;
    char buffer[256];
    const nub_size_t max_buffer_cstr_length = sizeof(buffer)-1;
    buffer[max_buffer_cstr_length] = '\0';
    nub_size_t length = 0;
    nub_addr_t curr_addr = addr;
    do
    {
        nub_size_t bytes_read = DNBProcessMemoryRead(pid, curr_addr, max_buffer_cstr_length, buffer);
        if (bytes_read == 0)
            break;
        length = strlen(buffer);
        cstr.append(buffer, length);
        curr_addr += length;
    } while (length == max_buffer_cstr_length);
    return cstr;
}

std::string
DNBProcessMemoryReadCStringFixed (nub_process_t pid, nub_addr_t addr, nub_size_t fixed_length)
{
    std::string cstr;
    char buffer[fixed_length+1];
    buffer[fixed_length] = '\0';
    nub_size_t bytes_read = DNBProcessMemoryRead(pid, addr, fixed_length, buffer);
    if (bytes_read > 0)
        cstr.assign(buffer);
    return cstr;
}


//----------------------------------------------------------------------
// Write memory to the address space of process PID. This call will take
// care of setting and restoring permissions and breaking up the memory
// write into multiple chunks as required.
//
// RETURNS: number of bytes actually written
//----------------------------------------------------------------------
nub_size_t
DNBProcessMemoryWrite (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->WriteMemory(addr, size, buf);
    return 0;
}

nub_addr_t
DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Task().AllocateMemory (size, permissions);
    return 0;
}

nub_bool_t
DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Task().DeallocateMemory (addr);
    return 0;
}

//----------------------------------------------------------------------
// Find attributes of the memory region that contains ADDR for process PID,
// if possible, and return a string describing those attributes.
//
// Returns 1 if we could find attributes for this region and OUTBUF can
// be sent to the remote debugger.
//
// Returns 0 if we couldn't find the attributes for a region of memory at
// that address and OUTBUF should not be sent.
//
// Returns -1 if this platform cannot look up information about memory regions
// or if we do not yet have a valid launched process.
//
//----------------------------------------------------------------------
int
DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Task().GetMemoryRegionInfo (addr, region_info);

    return -1;
}

std::string
DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->Task().GetProfileData(scanType);
    
    return std::string("");
}

nub_bool_t
DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SetEnableAsyncProfiling(enable, interval_usec, scan_type);
        return true;
    }
    
    return false;    
}

//----------------------------------------------------------------------
// Get the number of threads for the specified process.
//----------------------------------------------------------------------
nub_size_t
DNBProcessGetNumThreads (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetNumThreads();
    return 0;
}

//----------------------------------------------------------------------
// Get the thread ID of the current thread.
//----------------------------------------------------------------------
nub_thread_t
DNBProcessGetCurrentThread (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetCurrentThread();
    return 0;
}

//----------------------------------------------------------------------
// Get the mach port number of the current thread.
//----------------------------------------------------------------------
nub_thread_t
DNBProcessGetCurrentThreadMachPort (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetCurrentThreadMachPort();
    return 0;
}

//----------------------------------------------------------------------
// Change the current thread.
//----------------------------------------------------------------------
nub_thread_t
DNBProcessSetCurrentThread (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->SetCurrentThread (tid);
    return INVALID_NUB_THREAD;
}


//----------------------------------------------------------------------
// Dump a string describing a thread's stop reason to the specified file
// handle
//----------------------------------------------------------------------
nub_bool_t
DNBThreadGetStopReason (nub_process_t pid, nub_thread_t tid, struct DNBThreadStopInfo *stop_info)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetThreadStoppedReason (tid, stop_info);
    return false;
}

//----------------------------------------------------------------------
// Return string description for the specified thread.
//
// RETURNS: NULL if the thread isn't valid, else a NULL terminated C
// string from a static buffer that must be copied prior to subsequent
// calls.
//----------------------------------------------------------------------
const char *
DNBThreadGetInfo (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetThreadInfo (tid);
    return NULL;
}

//----------------------------------------------------------------------
// Get the thread ID given a thread index.
//----------------------------------------------------------------------
nub_thread_t
DNBProcessGetThreadAtIndex (nub_process_t pid, size_t thread_idx)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetThreadAtIndex (thread_idx);
    return INVALID_NUB_THREAD;
}

//----------------------------------------------------------------------
// Do whatever is needed to sync the thread's register state with it's kernel values.
//----------------------------------------------------------------------
nub_bool_t
DNBProcessSyncThreadState (nub_process_t pid, nub_thread_t tid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->SyncThreadState (tid);
    return false;

}

nub_addr_t
DNBProcessGetSharedLibraryInfoAddress (nub_process_t pid)
{
    MachProcessSP procSP;
    DNBError err;
    if (GetProcessSP (pid, procSP))
        return procSP->Task().GetDYLDAllImageInfosAddress (err);
    return INVALID_NUB_ADDRESS;
}


nub_bool_t
DNBProcessSharedLibrariesUpdated(nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SharedLibrariesUpdated ();
        return true;
    }
    return false;
}

//----------------------------------------------------------------------
// Get the current shared library information for a process. Only return
// the shared libraries that have changed since the last shared library
// state changed event if only_changed is non-zero.
//----------------------------------------------------------------------
nub_size_t
DNBProcessGetSharedLibraryInfo (nub_process_t pid, nub_bool_t only_changed, struct DNBExecutableImageInfo **image_infos)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->CopyImageInfos (image_infos, only_changed);

    // If we have no process, then return NULL for the shared library info
    // and zero for shared library count
    *image_infos = NULL;
    return 0;
}

uint32_t
DNBGetRegisterCPUType()
{
    return DNBArchProtocol::GetRegisterCPUType ();

}
//----------------------------------------------------------------------
// Get the register set information for a specific thread.
//----------------------------------------------------------------------
const DNBRegisterSetInfo *
DNBGetRegisterSetInfo (nub_size_t *num_reg_sets)
{
    return DNBArchProtocol::GetRegisterSetInfo (num_reg_sets);
}


//----------------------------------------------------------------------
// Read a register value by register set and register index.
//----------------------------------------------------------------------
nub_bool_t
DNBThreadGetRegisterValueByID (nub_process_t pid, nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *value)
{
    MachProcessSP procSP;
    ::bzero (value, sizeof(DNBRegisterValue));
    if (GetProcessSP (pid, procSP))
    {
        if (tid != INVALID_NUB_THREAD)
            return procSP->GetRegisterValue (tid, set, reg, value);
    }
    return false;
}

nub_bool_t
DNBThreadSetRegisterValueByID (nub_process_t pid, nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *value)
{
    if (tid != INVALID_NUB_THREAD)
    {
        MachProcessSP procSP;
        if (GetProcessSP (pid, procSP))
            return procSP->SetRegisterValue (tid, set, reg, value);
    }
    return false;
}

nub_size_t
DNBThreadGetRegisterContext (nub_process_t pid, nub_thread_t tid, void *buf, size_t buf_len)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        if (tid != INVALID_NUB_THREAD)
            return procSP->GetThreadList().GetRegisterContext (tid, buf, buf_len);
    }
    ::bzero (buf, buf_len);
    return 0;

}

nub_size_t
DNBThreadSetRegisterContext (nub_process_t pid, nub_thread_t tid, const void *buf, size_t buf_len)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        if (tid != INVALID_NUB_THREAD)
            return procSP->GetThreadList().SetRegisterContext (tid, buf, buf_len);
    }
    return 0;
}

uint32_t
DNBThreadSaveRegisterState (nub_process_t pid, nub_thread_t tid)
{
    if (tid != INVALID_NUB_THREAD)
    {
        MachProcessSP procSP;
        if (GetProcessSP (pid, procSP))
            return procSP->GetThreadList().SaveRegisterState (tid);
    }
    return 0;    
}
nub_bool_t
DNBThreadRestoreRegisterState (nub_process_t pid, nub_thread_t tid, uint32_t save_id)
{
    if (tid != INVALID_NUB_THREAD)
    {
        MachProcessSP procSP;
        if (GetProcessSP (pid, procSP))
            return procSP->GetThreadList().RestoreRegisterState (tid, save_id);
    }
    return false;
}



//----------------------------------------------------------------------
// Read a register value by name.
//----------------------------------------------------------------------
nub_bool_t
DNBThreadGetRegisterValueByName (nub_process_t pid, nub_thread_t tid, uint32_t reg_set, const char *reg_name, DNBRegisterValue *value)
{
    MachProcessSP procSP;
    ::bzero (value, sizeof(DNBRegisterValue));
    if (GetProcessSP (pid, procSP))
    {
        const struct DNBRegisterSetInfo *set_info;
        nub_size_t num_reg_sets = 0;
        set_info = DNBGetRegisterSetInfo (&num_reg_sets);
        if (set_info)
        {
            uint32_t set = reg_set;
            uint32_t reg;
            if (set == REGISTER_SET_ALL)
            {
                for (set = 1; set < num_reg_sets; ++set)
                {
                    for (reg = 0; reg < set_info[set].num_registers; ++reg)
                    {
                        if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
                            return procSP->GetRegisterValue (tid, set, reg, value);
                    }
                }
            }
            else
            {
                for (reg = 0; reg < set_info[set].num_registers; ++reg)
                {
                    if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
                        return procSP->GetRegisterValue (tid, set, reg, value);
                }
            }
        }
    }
    return false;
}


//----------------------------------------------------------------------
// Read a register set and register number from the register name.
//----------------------------------------------------------------------
nub_bool_t
DNBGetRegisterInfoByName (const char *reg_name, DNBRegisterInfo* info)
{
    const struct DNBRegisterSetInfo *set_info;
    nub_size_t num_reg_sets = 0;
    set_info = DNBGetRegisterSetInfo (&num_reg_sets);
    if (set_info)
    {
        uint32_t set, reg;
        for (set = 1; set < num_reg_sets; ++set)
        {
            for (reg = 0; reg < set_info[set].num_registers; ++reg)
            {
                if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
                {
                    *info = set_info[set].registers[reg];
                    return true;
                }
            }
        }

        for (set = 1; set < num_reg_sets; ++set)
        {
            uint32_t reg;
            for (reg = 0; reg < set_info[set].num_registers; ++reg)
            {
                if (set_info[set].registers[reg].alt == NULL)
                    continue;

                if (strcasecmp(reg_name, set_info[set].registers[reg].alt) == 0)
                {
                    *info = set_info[set].registers[reg];
                    return true;
                }
            }
        }
    }

    ::bzero (info, sizeof(DNBRegisterInfo));
    return false;
}


//----------------------------------------------------------------------
// Set the name to address callback function that this nub can use
// for any name to address lookups that are needed.
//----------------------------------------------------------------------
nub_bool_t
DNBProcessSetNameToAddressCallback (nub_process_t pid, DNBCallbackNameToAddress callback, void *baton)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SetNameToAddressCallback (callback, baton);
        return true;
    }
    return false;
}


//----------------------------------------------------------------------
// Set the name to address callback function that this nub can use
// for any name to address lookups that are needed.
//----------------------------------------------------------------------
nub_bool_t
DNBProcessSetSharedLibraryInfoCallback (nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback, void  *baton)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        procSP->SetSharedLibraryInfoCallback (callback, baton);
        return true;
    }
    return false;
}

nub_addr_t
DNBProcessLookupAddress (nub_process_t pid, const char *name, const char *shlib)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->LookupSymbol (name, shlib);
    }
    return INVALID_NUB_ADDRESS;
}


nub_size_t
DNBProcessGetAvailableSTDOUT (nub_process_t pid, char *buf, nub_size_t buf_size)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetAvailableSTDOUT (buf, buf_size);
    return 0;
}

nub_size_t
DNBProcessGetAvailableSTDERR (nub_process_t pid, char *buf, nub_size_t buf_size)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetAvailableSTDERR (buf, buf_size);
    return 0;
}

nub_size_t
DNBProcessGetAvailableProfileData (nub_process_t pid, char *buf, nub_size_t buf_size)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetAsyncProfileData (buf, buf_size);
    return 0;
}

nub_size_t
DNBProcessGetStopCount (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->StopCount();
    return 0;
}

uint32_t
DNBProcessGetCPUType (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
        return procSP->GetCPUType ();
    return 0;
    
}

nub_bool_t
DNBResolveExecutablePath (const char *path, char *resolved_path, size_t resolved_path_size)
{
    if (path == NULL || path[0] == '\0')
        return false;

    char max_path[PATH_MAX];
    std::string result;
    CFString::GlobPath(path, result);

    if (result.empty())
        result = path;
    
    struct stat path_stat;
    if (::stat(path, &path_stat) == 0)
    {
        if ((path_stat.st_mode & S_IFMT) == S_IFDIR)
        {
            CFBundle bundle (path);
            CFReleaser<CFURLRef> url(bundle.CopyExecutableURL ());
            if (url.get())
            {
                if (::CFURLGetFileSystemRepresentation (url.get(), true, (UInt8*)resolved_path, resolved_path_size))
                    return true;
            }
        }
    }

    if (realpath(path, max_path))
    {
        // Found the path relatively...
        ::strncpy(resolved_path, max_path, resolved_path_size);
        return strlen(resolved_path) + 1 < resolved_path_size;
    }
    else
    {
        // Not a relative path, check the PATH environment variable if the
        const char *PATH = getenv("PATH");
        if (PATH)
        {
            const char *curr_path_start = PATH;
            const char *curr_path_end;
            while (curr_path_start && *curr_path_start)
            {
                curr_path_end = strchr(curr_path_start, ':');
                if (curr_path_end == NULL)
                {
                    result.assign(curr_path_start);
                    curr_path_start = NULL;
                }
                else if (curr_path_end > curr_path_start)
                {
                    size_t len = curr_path_end - curr_path_start;
                    result.assign(curr_path_start, len);
                    curr_path_start += len + 1;
                }
                else
                    break;

                result += '/';
                result += path;
                struct stat s;
                if (stat(result.c_str(), &s) == 0)
                {
                    ::strncpy(resolved_path, result.c_str(), resolved_path_size);
                    return result.size() + 1 < resolved_path_size;
                }
            }
        }
    }
    return false;
}


void
DNBInitialize()
{
    DNBLogThreadedIf (LOG_PROCESS, "DNBInitialize ()");
#if defined (__i386__) || defined (__x86_64__)
    DNBArchImplI386::Initialize();
    DNBArchImplX86_64::Initialize();
#elif defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
    DNBArchMachARM::Initialize();
    DNBArchMachARM64::Initialize();
#endif
}

void
DNBTerminate()
{
}

nub_bool_t
DNBSetArchitecture (const char *arch)
{
    if (arch && arch[0])
    {
        if (strcasecmp (arch, "i386") == 0)
            return DNBArchProtocol::SetArchitecture (CPU_TYPE_I386);
        else if ((strcasecmp (arch, "x86_64") == 0) || (strcasecmp (arch, "x86_64h") == 0))
            return DNBArchProtocol::SetArchitecture (CPU_TYPE_X86_64);
        else if (strstr (arch, "arm64") == arch || strstr (arch, "armv8") == arch || strstr (arch, "aarch64") == arch)
            return DNBArchProtocol::SetArchitecture (CPU_TYPE_ARM64);
        else if (strstr (arch, "arm") == arch)
            return DNBArchProtocol::SetArchitecture (CPU_TYPE_ARM);
    }
    return false;
}
