//===-- 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 <libproc.h>
#include <map>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>

#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 "CFBundle.h"
#include "CFString.h"
#include "DNBDataRef.h"
#include "DNBLog.h"
#include "DNBThreadResumeActions.h"
#include "DNBTimer.h"
#include "MacOSX/DarwinLog/DarwinLogCollector.h"
#include "MacOSX/Genealogy.h"
#include "MacOSX/MachProcess.h"
#include "MacOSX/MachTask.h"
#include "MacOSX/ThreadInfo.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) {
          strlcpy(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;
}

const char *DNBGetDeploymentInfo(nub_process_t pid,
                                 const struct load_command& lc,
                                 uint64_t load_command_address,
                                 uint32_t& major_version,
                                 uint32_t& minor_version,
                                 uint32_t& patch_version) {
  MachProcessSP procSP;
  if (GetProcessSP(pid, procSP))
    return procSP->GetDeploymentInfo(lc, load_command_address,
                                     major_version, minor_version,
                                     patch_version);
  return nullptr;
}


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

DarwinLogEventVector DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid) {
  return DarwinLogCollector::GetEventsForProcess(pid);
}

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...
    ::strlcpy(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) {
          ::strlcpy(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;
}
