//===-- 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, static_cast<void *>(argv), static_cast<void *>(envp), working_directory,
                     stdin_path, stdout_path, stderr_path, no_stdio, launch_flavor, disable_aslr,
                     static_cast<void *>(err_str), static_cast<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);
                UNUSED_IF_ASSERT_DISABLED(res);
                assert(res && "Couldn't add process to map!");
                return pid;
            }
        }
    }
    return INVALID_NUB_PROCESS;
}

// If there is one process with a given name, return the pid for that process.
nub_process_t
DNBProcessGetPIDByName (const char *name)
{
    std::vector<struct kinfo_proc> matching_proc_infos;
    size_t num_matching_proc_infos = GetAllInfosMatchingName(name, matching_proc_infos);
    if (num_matching_proc_infos == 1)
    {
        return matching_proc_infos[0].kp_proc.p_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);
            UNUSED_IF_ASSERT_DISABLED(res);
            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)
                {
                    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, launch_flavor);
            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, launch_flavor, 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();
}

JSONGenerator::ObjectSP 
DNBGetAllLoadedLibrariesInfos (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetAllLoadedLibrariesInfos (pid);
    }
    return JSONGenerator::ObjectSP();
}

JSONGenerator::ObjectSP 
DNBGetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetLibrariesInfoForAddresses (pid, macho_addresses);
    }
    return JSONGenerator::ObjectSP();
}

JSONGenerator::ObjectSP 
DNBGetSharedCacheInfo (nub_process_t pid)
{
    MachProcessSP procSP;
    if (GetProcessSP (pid, procSP))
    {
        return procSP->GetSharedCacheInfo (pid);
    }
    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;
}

bool
DNBGetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *patch)
{
    return MachProcess::GetOSVersionNumbers (major, minor, patch);
}


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