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

#include "NativeProcessDarwin.h"

// C includes
#include <mach/mach_init.h>
#include <mach/mach_traps.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>

// C++ includes
// LLDB includes
#include "lldb/Core/State.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

#include "CFBundle.h"
#include "CFString.h"
#include "DarwinProcessLauncher.h"

#include "MachException.h"

#include "llvm/Support/FileSystem.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_darwin;
using namespace lldb_private::darwin_process_launcher;

// -----------------------------------------------------------------------------
// Hidden Impl
// -----------------------------------------------------------------------------

namespace {
struct hack_task_dyld_info {
  mach_vm_address_t all_image_info_addr;
  mach_vm_size_t all_image_info_size;
};
}

// -----------------------------------------------------------------------------
// Public Static Methods
// -----------------------------------------------------------------------------

Status NativeProcessProtocol::Launch(
    ProcessLaunchInfo &launch_info,
    NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
    NativeProcessProtocolSP &native_process_sp) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  Status error;

  // Verify the working directory is valid if one was specified.
  FileSpec working_dir(launch_info.GetWorkingDirectory());
  if (working_dir &&
      (!working_dir.ResolvePath() ||
       !llvm::sys::fs::is_directory(working_dir.GetPath())) {
    error.SetErrorStringWithFormat("No such file or directory: %s",
                                   working_dir.GetCString());
    return error;
  }

  // Launch the inferior.
  int pty_master_fd = -1;
  LaunchFlavor launch_flavor = LaunchFlavor::Default;

  error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);

  // Handle launch failure.
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() failed to launch process: "
                  "%s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Handle failure to return a pid.
  if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
                  "pid was returned!  Aborting.",
                  __FUNCTION__);
    return error;
  }

  // Create the Darwin native process impl.
  std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
      new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
  if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
    native_process_sp.reset();
    error.SetErrorStringWithFormat("failed to register the native delegate");
    return error;
  }

  // Finalize the processing needed to debug the launched process with
  // a NativeProcessDarwin instance.
  error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
                  " the launching of the process: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Return the process and process id to the caller through the launch args.
  native_process_sp = np_darwin_sp;
  return error;
}

Status NativeProcessProtocol::Attach(
    lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
    MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (log)
    log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
                pid);

  // Retrieve the architecture for the running process.
  ArchSpec process_arch;
  Status error = ResolveProcessArchitecture(pid, process_arch);
  if (!error.Success())
    return error;

  // TODO get attach to return this value.
  const int pty_master_fd = -1;
  std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
      new NativeProcessDarwin(pid, pty_master_fd));

  if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
    error.SetErrorStringWithFormat("failed to register the native "
                                   "delegate");
    return error;
  }

  native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
  if (!error.Success())
    return error;

  native_process_sp = native_process_darwin_sp;
  return error;
}

// -----------------------------------------------------------------------------
// ctor/dtor
// -----------------------------------------------------------------------------

NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
    : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
      m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
      m_exception_thread(nullptr), m_exception_messages_mutex(),
      m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
      m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
      m_waitpid_reader_handle() {
  // TODO add this to the NativeProcessProtocol constructor.
  m_terminal_fd = pty_master_fd;
}

NativeProcessDarwin::~NativeProcessDarwin() {}

// -----------------------------------------------------------------------------
// Instance methods
// -----------------------------------------------------------------------------

Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
                                           MainLoop &main_loop) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

#if 0
    m_path = path;
    size_t i;
    char const *arg;
    for (i=0; (arg = argv[i]) != NULL; i++)
        m_args.push_back(arg);
#endif

  error = StartExceptionThread();
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failure starting the "
                  "mach exception port monitor thread: %s",
                  __FUNCTION__, error.AsCString());

    // Terminate the inferior process.  There's nothing meaningful we can
    // do if we can't receive signals and exceptions.  Since we launched
    // the process, it's fair game for us to kill it.
    ::ptrace(PT_KILL, m_pid, 0, 0);
    SetState(eStateExited);

    return error;
  }

  StartSTDIOThread();

  if (launch_flavor == LaunchFlavor::PosixSpawn) {
    SetState(eStateAttaching);
    errno = 0;
    int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
    if (err == 0) {
      // m_flags |= eMachProcessFlagsAttached;
      if (log)
        log->Printf("NativeProcessDarwin::%s(): successfully spawned "
                    "process with pid %" PRIu64,
                    __FUNCTION__, m_pid);
    } else {
      error.SetErrorToErrno();
      SetState(eStateExited);
      if (log)
        log->Printf("NativeProcessDarwin::%s(): error: failed to "
                    "attach to spawned pid %" PRIu64 " (error=%d (%s))",
                    __FUNCTION__, m_pid, (int)error.GetError(),
                    error.AsCString());
      return error;
    }
  }

  if (log)
    log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
                __FUNCTION__, m_pid);

  // Spawn a thread to reap our child inferior process...
  error = StartWaitpidThread(main_loop);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
                  "thread: %s",
                  __FUNCTION__, error.AsCString());
    kill(SIGKILL, static_cast<::pid_t>(m_pid));
    return error;
  }

  if (TaskPortForProcessID(error) == 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.
    if (log)
      log->Printf("NativeProcessDarwin::%s(): could not get task port "
                  "for process, sending SIGKILL and exiting: %s",
                  __FUNCTION__, error.AsCString());
    kill(SIGKILL, static_cast<::pid_t>(m_pid));
    return error;
  }

  // Indicate that we're stopped, as we always launch suspended.
  SetState(eStateStopped);

  // Success.
  return error;
}

Status NativeProcessDarwin::SaveExceptionPortInfo() {
  return m_exc_port_info.Save(m_task);
}

bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
  // TODO implement flags
  // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
  return false;
}

bool NativeProcessDarwin::ProcessUsingBackBoard() const {
  // TODO implement flags
  // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
  return false;
}

// Called by the exception thread when an exception has been received from
// our process. The exception message is completely filled and the exception
// data has already been copied.
void NativeProcessDarwin::ExceptionMessageReceived(
    const MachException::Message &message) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS ));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (m_exception_messages.empty()) {
    // Suspend the task the moment we receive our first exception message.
    SuspendTask();
  }

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

  if (log)
    log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
                __FUNCTION__, m_exception_messages.size());
}

void *NativeProcessDarwin::ExceptionThread(void *arg) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS ));
  if (!arg) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
                  "thread, mandatory process arg was null",
                  __FUNCTION__);
    return nullptr;
  }

  return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
}

void *NativeProcessDarwin::DoExceptionThread() {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS ));

  if (log)
    log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
                __FUNCTION__, this);

  pthread_setname_np("exception monitoring thread");

  // Ensure we don't get CPU starved.
  MaybeRaiseThreadPriority();

  // We keep a count of the number of consecutive exceptions received so
  // we know to grab all exceptions without a timeout. We do this to get a
  // bunch of related exceptions on our exception port so we can process
  // then together. When we have multiple threads, we can get an exception
  // per thread and they will come in consecutively. The main loop in this
  // thread can stop periodically if needed to service things related to this
  // process.
  //
  // [did we lose some words here?]
  //
  // flag set in the options, so we will wait forever for an exception on
  // 0 our exception port. After we get one exception, we then will use the
  // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
  // exceptions for our process. After we have received the last pending
  // exception, we will get a timeout which enables us to then notify
  // our main thread that we have an exception bundle available. We then wait
  // for the main thread to tell this exception thread to start trying to get
  // exceptions messages again and we start again with a mach_msg read with
  // infinite timeout.
  //
  // We choose to park a thread on this, rather than polling, because the
  // polling is expensive.  On devices, we need to minimize overhead caused
  // by the process monitor.
  uint32_t num_exceptions_received = 0;
  Status error;
  task_t task = m_task;
  mach_msg_timeout_t periodic_timeout = 0;

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
  mach_msg_timeout_t watchdog_elapsed = 0;
  mach_msg_timeout_t watchdog_timeout = 60 * 1000;
  ::pid_t pid = (::pid_t)process->GetID();
  CFReleaser<SBSWatchdogAssertionRef> watchdog;

  if (process->ProcessUsingSpringBoard()) {
    // Request a renewal for every 60 seconds if we attached using
    // SpringBoard.
    watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
    if (log)
      log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
                  "=> %p",
                  pid, watchdog.get());

    if (watchdog.get()) {
      ::SBSWatchdogAssertionRenew(watchdog.get());

      CFTimeInterval watchdogRenewalInterval =
          ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
      if (log)
        log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
                    "%g seconds",
                    watchdog.get(), watchdogRenewalInterval);
      if (watchdogRenewalInterval > 0.0) {
        watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
        if (watchdog_timeout > 3000) {
          // Give us a second to renew our timeout.
          watchdog_timeout -= 1000;
        } else if (watchdog_timeout > 1000) {
          // Give us a quarter of a second to renew our timeout.
          watchdog_timeout -= 250;
        }
      }
    }
    if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
      periodic_timeout = watchdog_timeout;
  }
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)

#ifdef WITH_BKS
  CFReleaser<BKSWatchdogAssertionRef> watchdog;
  if (process->ProcessUsingBackBoard()) {
    ::pid_t pid = process->GetID();
    CFAllocatorRef alloc = kCFAllocatorDefault;
    watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
  }
#endif // #ifdef WITH_BKS

  // Do we want to use a weak pointer to the NativeProcessDarwin here, in
  // which case we can guarantee we don't whack the process monitor if we
  // race between this thread and the main one on shutdown?
  while (IsExceptionPortValid()) {
    ::pthread_testcancel();

    MachException::Message exception_message;

    if (num_exceptions_received > 0) {
      // We don't want a timeout here, just receive as many exceptions as
      // we can since we already have one.  We want to get all currently
      // available exceptions for this task at once.
      error = exception_message.Receive(
          GetExceptionPort(),
          MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
    } else if (periodic_timeout > 0) {
      // We need to stop periodically in this loop, so try and get a mach
      // message with a valid timeout (ms).
      error = exception_message.Receive(GetExceptionPort(),
                                        MACH_RCV_MSG | MACH_RCV_INTERRUPT |
                                            MACH_RCV_TIMEOUT,
                                        periodic_timeout);
    } else {
      // We don't need to parse all current exceptions or stop
      // periodically, just wait for an exception forever.
      error = exception_message.Receive(GetExceptionPort(),
                                        MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
    }

    if (error.Success()) {
      // We successfully received an exception.
      if (exception_message.CatchExceptionRaise(task)) {
        ++num_exceptions_received;
        ExceptionMessageReceived(exception_message);
      }
    } else {
      if (error.GetError() == MACH_RCV_INTERRUPTED) {
        // We were interrupted.

        // If we have no task port we should exit this thread, as it implies
        // the inferior went down.
        if (!IsExceptionPortValid()) {
          if (log)
            log->Printf("NativeProcessDarwin::%s(): the inferior "
                        "exception port is no longer valid, "
                        "canceling exception thread...",
                        __FUNCTION__);
          // Should we be setting a process state here?
          break;
        }

        // Make sure the inferior task is still valid.
        if (IsTaskValid()) {
          // Task is still ok.
          if (log)
            log->Printf("NativeProcessDarwin::%s(): interrupted, but "
                        "the inferior task iss till valid, "
                        "continuing...",
                        __FUNCTION__);
          continue;
        } else {
          // The inferior task is no longer valid.  Time to exit as
          // the process has gone away.
          if (log)
            log->Printf("NativeProcessDarwin::%s(): the inferior task "
                        "has exited, and so will we...",
                        __FUNCTION__);
          // Does this race at all with our waitpid()?
          SetState(eStateExited);
          break;
        }
      } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
        // We timed out when waiting for exceptions.

        if (num_exceptions_received > 0) {
          // We were receiving all current exceptions with a timeout of
          // zero.  It is time to go back to our normal looping mode.
          num_exceptions_received = 0;

          // Notify our main thread we have a complete exception message
          // bundle available.  Get the possibly updated task port back
          // from the process in case we exec'ed and our task port
          // changed.
          task = ExceptionMessageBundleComplete();

          // In case we use a timeout value when getting exceptions,
          // make sure our task is still valid.
          if (IsTaskValid(task)) {
            // Task is still ok.
            if (log)
              log->Printf("NativeProcessDarwin::%s(): got a timeout, "
                          "continuing...",
                          __FUNCTION__);
            continue;
          } else {
            // The inferior task is no longer valid.  Time to exit as
            // the process has gone away.
            if (log)
              log->Printf("NativeProcessDarwin::%s(): the inferior "
                          "task has exited, and so will we...",
                          __FUNCTION__);
            // Does this race at all with our waitpid()?
            SetState(eStateExited);
            break;
          }
        }

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
        if (watchdog.get()) {
          watchdog_elapsed += periodic_timeout;
          if (watchdog_elapsed >= watchdog_timeout) {
            if (log)
              log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
            ::SBSWatchdogAssertionRenew(watchdog.get());
            watchdog_elapsed = 0;
          }
        }
#endif
      } else {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): continuing after "
                      "receiving an unexpected error: %u (%s)",
                      __FUNCTION__, error.GetError(), error.AsCString());
        // TODO: notify of error?
      }
    }
  }

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
  if (watchdog.get()) {
    // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
    // when we
    // all are up and running on systems that support it. The SBS framework has
    // a #define
    // that will forward SBSWatchdogAssertionRelease to
    // SBSWatchdogAssertionCancel for now
    // so it should still build either way.
    DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
                     watchdog.get());
    ::SBSWatchdogAssertionRelease(watchdog.get());
  }
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)

  if (log)
    log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
                this);
  return nullptr;
}

Status NativeProcessDarwin::StartExceptionThread() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (log)
    log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);

  // Make sure we've looked up the inferior port.
  TaskPortForProcessID(error);

  // Ensure the inferior task is valid.
  if (!IsTaskValid()) {
    error.SetErrorStringWithFormat("cannot start exception thread: "
                                   "task 0x%4.4x is not valid",
                                   m_task);
    return error;
  }

  // Get the mach port for the process monitor.
  mach_port_t task_self = mach_task_self();

  // Allocate an exception port that we will use to track our child process
  auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
                                       &m_exception_port);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
                  "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
                  "&m_exception_port) failed: %u (%s)",
                  __FUNCTION__, task_self, error.GetError(), error.AsCString());
    return error;
  }

  // Add the ability to send messages on the new exception port
  mach_err = ::mach_port_insert_right(
      task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
                  "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
                  "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
                  "failed: %u (%s)",
                  __FUNCTION__, task_self, m_exception_port, m_exception_port,
                  error.GetError(), error.AsCString());
    return error;
  }

  // Save the original state of the exception ports for our child process.
  error = SaveExceptionPortInfo();
  if (error.Fail() || (m_exc_port_info.mask == 0)) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
                  "failed, cannot install exception handler: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Set the ability to get all exceptions on this port.
  mach_err = ::task_set_exception_ports(
      m_task, m_exc_port_info.mask, m_exception_port,
      EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
                  "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
                  "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
                  "%u (%s)",
                  m_task, m_exc_port_info.mask, m_exception_port,
                  (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
                  error.GetError(), error.AsCString());
    return error;
  }

  // Create the exception thread.
  auto pthread_err =
      ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
  error.SetError(pthread_err, eErrorTypePOSIX);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
                  "exception-handling thread: %u (%s)",
                  __FUNCTION__, error.GetError(), error.AsCString());
  }

  return error;
}

lldb::addr_t
NativeProcessDarwin::GetDYLDAllImageInfosAddress(Status &error) const {
  error.Clear();

  struct hack_task_dyld_info dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  // Make sure that COUNT isn't bigger than our hacked up struct
  // hack_task_dyld_info.  If it is, then make COUNT smaller to match.
  if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
    count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
  }

  TaskPortForProcessID(error);
  if (error.Fail())
    return LLDB_INVALID_ADDRESS;

  auto mach_err =
      ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Success()) {
    // We now have the address of the all image infos structure.
    return dyld_info.all_image_info_addr;
  }

  // We don't have it.
  return LLDB_INVALID_ADDRESS;
}

uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
  int mib[CTL_MAXNAME] = {
      0,
  };
  size_t len = CTL_MAXNAME;

  if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
    return 0;

  mib[len] = pid;
  len++;

  cpu_type_t cpu;
  size_t cpu_len = sizeof(cpu);
  if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
    cpu = 0;
  return cpu;
}

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

task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
  // We have a complete bundle of exceptions for our child process.
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (log)
    log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
                "messages.",
                __FUNCTION__, m_exception_messages.size());

  if (m_exception_messages.empty()) {
    // Not particularly useful...
    return m_task;
  }

  bool auto_resume = false;
  m_did_exec = false;

  // First check for any SIGTRAP and make sure we didn't exec
  const task_t task = m_task;
  size_t i;
  if (m_pid != 0) {
    bool received_interrupt = false;
    uint32_t num_task_exceptions = 0;
    for (i = 0; i < m_exception_messages.size(); ++i) {
      if (m_exception_messages[i].state.task_port != task) {
        // This is an exception that is not for our inferior, ignore.
        continue;
      }

      // This is an exception for the inferior.
      ++num_task_exceptions;
      const int signo = m_exception_messages[i].state.SoftSignal();
      if (signo == SIGTRAP) {
        // SIGTRAP could mean that we exec'ed. We need to check the
        // dyld all_image_infos.infoArray to see if it is NULL and if
        // so, say that we exec'ed.
        const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
        if (aii_addr == LLDB_INVALID_ADDRESS)
          break;

        const addr_t info_array_count_addr = aii_addr + 4;
        uint32_t info_array_count = 0;
        size_t bytes_read = 0;
        Status read_error;
        read_error = ReadMemory(info_array_count_addr, // source addr
                                &info_array_count,     // dest addr
                                4,                     // byte count
                                bytes_read);           // #bytes read
        if (read_error.Success() && (bytes_read == 4)) {
          if (info_array_count == 0) {
            // We got the all infos address, and there are zero
            // entries.  We think we exec'd.
            m_did_exec = true;

            // Force the task port to update itself in case the
            // task port changed after exec
            const task_t old_task = m_task;
            const bool force_update = true;
            const task_t new_task = TaskPortForProcessID(error, force_update);
            if (old_task != new_task) {
              if (log)
                log->Printf("exec: inferior task port changed "
                            "from 0x%4.4x to 0x%4.4x",
                            old_task, new_task);
            }
          }
        } else {
          if (log)
            log->Printf("NativeProcessDarwin::%s() warning: "
                        "failed to read all_image_infos."
                        "infoArrayCount from 0x%8.8llx",
                        __FUNCTION__, info_array_count_addr);
        }
      } else if ((m_sent_interrupt_signo != 0) &&
                 (signo == m_sent_interrupt_signo)) {
        // We just received the interrupt that we sent to ourselves.
        received_interrupt = true;
      }
    }

    if (m_did_exec) {
      cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
      if (m_cpu_type != process_cpu_type) {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): arch changed from "
                      "0x%8.8x to 0x%8.8x",
                      __FUNCTION__, m_cpu_type, process_cpu_type);
        m_cpu_type = process_cpu_type;
        // TODO figure out if we need to do something here.
        // DNBArchProtocol::SetArchitecture (process_cpu_type);
      }
      m_thread_list.Clear();

      // TODO hook up breakpoints.
      // m_breakpoints.DisableAll();
    }

    if (m_sent_interrupt_signo != 0) {
      if (received_interrupt) {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): process "
                      "successfully interrupted with signal %i",
                      __FUNCTION__, m_sent_interrupt_signo);

        // Mark that we received the interrupt signal
        m_sent_interrupt_signo = 0;
        // Now check if we had a case where:
        // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
        //     for another reason.
        // 2 - We called NativeProcessDarwin::Resume() (but still
        //     haven't gotten the interrupt signal).
        // 3 - We are now incorrectly stopped because we are handling
        //     the interrupt signal we missed.
        // 4 - We might need to resume if we stopped only with the
        //     interrupt signal that we never handled.
        if (m_auto_resume_signo != 0) {
          // Only auto_resume if we stopped with _only_ the interrupt
          // signal.
          if (num_task_exceptions == 1) {
            auto_resume = true;
            if (log)
              log->Printf("NativeProcessDarwin::%s(): auto "
                          "resuming due to unhandled interrupt "
                          "signal %i",
                          __FUNCTION__, m_auto_resume_signo);
          }
          m_auto_resume_signo = 0;
        }
      } else {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): didn't get signal "
                      "%i after MachProcess::Interrupt()",
                      __FUNCTION__, m_sent_interrupt_signo);
      }
    }
  }

  // Let all threads recover from stopping and do any clean up based
  // on the previous thread state (if any).
  m_thread_list.ProcessDidStop(*this);

  // Let each thread know of any exceptions
  for (i = 0; i < m_exception_messages.size(); ++i) {
    // Let the thread list forward all exceptions on down to each thread.
    if (m_exception_messages[i].state.task_port == task) {
      // This exception is for our inferior.
      m_thread_list.NotifyException(m_exception_messages[i].state);
    }

    if (log) {
      StreamString stream;
      m_exception_messages[i].Dump(stream);
      stream.Flush();
      log->PutCString(stream.GetString().c_str());
    }
  }

  if (log) {
    StreamString stream;
    m_thread_list.Dump(stream);
    stream.Flush();
    log->PutCString(stream.GetString().c_str());
  }

  bool step_more = false;
  if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
// TODO - need to hook up event system here. !!!!
#if 0
        // Wait for the eEventProcessRunningStateChanged event to be reset
        // before changing state to stopped to avoid race condition with
        // very fast start/stops.
        struct timespec timeout;

        //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000);   // Wait for 250 ms
        DNBTimer::OffsetTimeOfDay(&timeout, 1, 0);  // Wait for 250 ms
        m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
                                      &timeout);
#endif
    SetState(eStateStopped);
  } else {
    // Resume without checking our current state.
    PrivateResume();
  }

  return m_task;
}

void NativeProcessDarwin::StartSTDIOThread() {
  // TODO implement
}

Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Strategy: create a thread that sits on waitpid(), waiting for the
  // inferior process to die, reaping it in the process.  Arrange for
  // the thread to have a pipe file descriptor that it can send a byte
  // over when the waitpid completes.  Have the main loop have a read
  // object for the other side of the pipe, and have the callback for
  // the read do the process termination message sending.

  // Create a single-direction communication channel.
  const bool child_inherits = false;
  error = m_waitpid_pipe.CreateNew(child_inherits);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
                  "communication pipe: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Hook up the waitpid reader callback.

  // TODO make PipePOSIX derive from IOObject.  This is goofy here.
  const bool transfer_ownership = false;
  auto io_sp = IOObjectSP(
      new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
  m_waitpid_reader_handle = main_loop.RegisterReadObject(
      io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);

  // Create the thread.
  auto pthread_err =
      ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
  error.SetError(pthread_err, eErrorTypePOSIX);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
                  "handling thread: %u (%s)",
                  __FUNCTION__, error.GetError(), error.AsCString());
    return error;
  }

  return error;
}

void *NativeProcessDarwin::WaitpidThread(void *arg) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (!arg) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
                  "thread, mandatory process arg was null",
                  __FUNCTION__);
    return nullptr;
  }

  return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
}

void NativeProcessDarwin::MaybeRaiseThreadPriority() {
#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
}

void *NativeProcessDarwin::DoWaitpidThread() {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  if (m_pid == LLDB_INVALID_PROCESS_ID) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
                  "not set, cannot waitpid on it",
                  __FUNCTION__);
    return nullptr;
  }

  // Name the thread.
  pthread_setname_np("waitpid thread");

  // Ensure we don't get CPU starved.
  MaybeRaiseThreadPriority();

  Status error;
  int status = -1;

  while (1) {
    // Do a waitpid.
    ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
    if (child_pid < 0)
      error.SetErrorToErrno();
    if (error.Fail()) {
      if (error.GetError() == EINTR) {
        // This is okay, we can keep going.
        if (log)
          log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                      ", &status, 0) interrupted, continuing",
                      __FUNCTION__, m_pid);
        continue;
      }

      // This error is not okay, abort.
      if (log)
        log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                    ", &status, 0) aborting due to error: %u (%s)",
                    __FUNCTION__, m_pid, error.GetError(), error.AsCString());
      break;
    }

    // Log the successful result.
    if (log)
      log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                  ", &status, 0) => %i, status = %i",
                  __FUNCTION__, m_pid, child_pid, status);

    // Handle the result.
    if (WIFSTOPPED(status)) {
      if (log)
        log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                    ") received a stop, continuing waitpid() loop",
                    __FUNCTION__, m_pid);
      continue;
    } else // if (WIFEXITED(status) || WIFSIGNALED(status))
    {
      if (log)
        log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
                    "waitpid thread is setting exit status for pid = "
                    "%i to %i",
                    __FUNCTION__, m_pid, child_pid, status);

      error = SendInferiorExitStatusToMainLoop(child_pid, status);
      return nullptr;
    }
  }

  // We should never exit as long as our child process is alive.  If we
  // get here, something completely unexpected went wrong and we should exit.
  if (log)
    log->Printf(
        "NativeProcessDarwin::%s(): internal error: waitpid thread "
        "exited out of its main loop in an unexpected way. pid = %" PRIu64
        ". Sending exit status of -1.",
        __FUNCTION__, m_pid);

  error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
  return nullptr;
}

Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
                                                             int status) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  size_t bytes_written = 0;

  // Send the pid.
  error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
  if (error.Fail() || (bytes_written < sizeof(pid))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to write "
                  "waitpid exiting pid to the pipe.  Client will not "
                  "hear about inferior exit status!",
                  __FUNCTION__);
    return error;
  }

  // Send the status.
  bytes_written = 0;
  error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
  if (error.Fail() || (bytes_written < sizeof(status))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to write "
                  "waitpid exit result to the pipe.  Client will not "
                  "hear about inferior exit status!",
                  __FUNCTION__);
  }
  return error;
}

Status NativeProcessDarwin::HandleWaitpidResult() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Read the pid.
  const bool notify_status = true;

  ::pid_t pid = -1;
  size_t bytes_read = 0;
  error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
  if (error.Fail() || (bytes_read < sizeof(pid))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to read "
                  "waitpid exiting pid from the pipe.  Will notify "
                  "as if parent process died with exit status -1.",
                  __FUNCTION__);
    SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
    return error;
  }

  // Read the status.
  int status = -1;
  error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
  if (error.Fail() || (bytes_read < sizeof(status))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to read "
                  "waitpid exit status from the pipe.  Will notify "
                  "as if parent process died with exit status -1.",
                  __FUNCTION__);
    SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
    return error;
  }

  // Notify the monitor that our state has changed.
  if (log)
    log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
                "exit status info: pid=%i (%s), status=%i",
                __FUNCTION__, pid,
                (pid == m_pid) ? "the inferior" : "not the inferior", status);

  SetExitStatus(WaitStatus::Decode(status), notify_status);
  return error;
}

task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
                                                 bool force) const {
  if ((m_task == TASK_NULL) || force) {
    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
    if (m_pid == LLDB_INVALID_PROCESS_ID) {
      if (log)
        log->Printf("NativeProcessDarwin::%s(): cannot get task due "
                    "to invalid pid",
                    __FUNCTION__);
      return TASK_NULL;
    }

    const uint32_t num_retries = 10;
    const uint32_t usec_interval = 10000;

    mach_port_t task_self = mach_task_self();
    task_t task = TASK_NULL;

    for (uint32_t i = 0; i < num_retries; i++) {
      kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
      if (err == 0) {
        // Succeeded.  Save and return it.
        error.Clear();
        m_task = task;
        log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
                    "stub_port = 0x%4.4x, pid = %llu, &task) "
                    "succeeded: inferior task port = 0x%4.4x",
                    __FUNCTION__, task_self, m_pid, m_task);
        return m_task;
      } else {
        // Failed to get the task for the inferior process.
        error.SetError(err, eErrorTypeMachKernel);
        if (log) {
          log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
                      "stub_port = 0x%4.4x, pid = %llu, &task) "
                      "failed, err = 0x%8.8x (%s)",
                      __FUNCTION__, task_self, m_pid, err, error.AsCString());
        }
      }

      // Sleep a bit and try again
      ::usleep(usec_interval);
    }

    // We failed to get the task for the inferior process.
    // Ensure that it is cleared out.
    m_task = TASK_NULL;
  }
  return m_task;
}

void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
                                           Status &error) {
  error.SetErrorString("TODO: implement");
}

Status NativeProcessDarwin::PrivateResume() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  m_auto_resume_signo = m_sent_interrupt_signo;

  if (log) {
    if (m_auto_resume_signo)
      log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
                  "unhandled interrupt signal %i)...",
                  __FUNCTION__, m_task, m_auto_resume_signo);
    else
      log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
                  __FUNCTION__, m_task);
  }

  error = ReplyToAllExceptions();
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
                  "reply to exceptions: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }
  //    bool stepOverBreakInstruction = step;

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

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

  // Now resume our task.
  error = ResumeTask();
  return error;
}

Status NativeProcessDarwin::ReplyToAllExceptions() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  TaskPortForProcessID(error);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
                  __FUNCTION__);
    return error;
  }

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (m_exception_messages.empty()) {
    // We're done.
    return error;
  }

  size_t index = 0;
  for (auto &message : m_exception_messages) {
    if (log) {
      log->Printf("NativeProcessDarwin::%s(): replying to exception "
                  "%zu...",
                  __FUNCTION__, index++);
    }

    int thread_reply_signal = 0;

    const tid_t tid =
        m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
    const ResumeAction *action = nullptr;
    if (tid != LLDB_INVALID_THREAD_ID)
      action = m_thread_actions.GetActionForThread(tid, false);

    if (action) {
      thread_reply_signal = action->signal;
      if (thread_reply_signal)
        m_thread_actions.SetSignalHandledForThread(tid);
    }

    error = message.Reply(m_pid, m_task, thread_reply_signal);
    if (error.Fail() && log) {
      // We log any error here, but we don't stop the exception
      // response handling.
      log->Printf("NativeProcessDarwin::%s(): failed to reply to "
                  "exception: %s",
                  __FUNCTION__, error.AsCString());
      error.Clear();
    }
  }

  // Erase all exception message as we should have used and replied
  // to them all already.
  m_exception_messages.clear();
  return error;
}

Status NativeProcessDarwin::ResumeTask() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  TaskPortForProcessID(error);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to get task port "
                  "for process when attempting to resume: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }
  if (m_task == TASK_NULL) {
    error.SetErrorString("task port retrieval succeeded but task port is "
                         "null when attempting to resume the task");
    return error;
  }

  if (log)
    log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
                "0x%4.4x",
                __FUNCTION__, m_task);

  // Get the BasicInfo struct to verify that we're suspended before we try
  // to resume the task.
  struct task_basic_info task_info;
  error = GetTaskBasicInfo(m_task, &task_info);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to get task "
                  "BasicInfo when attempting to resume: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // task_resume isn't counted like task_suspend calls are, so if the
  // task is not suspended, don't try and resume it since it is already
  // running
  if (task_info.suspend_count > 0) {
    auto mach_err = ::task_resume(m_task);
    error.SetError(mach_err, eErrorTypeMachKernel);
    if (log) {
      if (error.Success())
        log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
      else
        log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
                    error.AsCString());
    }
  } else {
    if (log)
      log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
                  "already running",
                  m_task);
  }

  return error;
}

bool NativeProcessDarwin::IsTaskValid() const {
  if (m_task == TASK_NULL)
    return false;

  struct task_basic_info task_info;
  return GetTaskBasicInfo(m_task, &task_info).Success();
}

bool NativeProcessDarwin::IsTaskValid(task_t task) const {
  if (task == TASK_NULL)
    return false;

  struct task_basic_info task_info;
  return GetTaskBasicInfo(task, &task_info).Success();
}

mach_port_t NativeProcessDarwin::GetExceptionPort() const {
  return m_exception_port;
}

bool NativeProcessDarwin::IsExceptionPortValid() const {
  return MACH_PORT_VALID(m_exception_port);
}

Status
NativeProcessDarwin::GetTaskBasicInfo(task_t task,
                                      struct task_basic_info *info) const {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Validate args.
  if (info == NULL) {
    error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
                                   "info arg is null",
                                   __FUNCTION__);
    return error;
  }

  // Grab the task if we don't already have it.
  if (task == TASK_NULL) {
    error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
                                   "is invalid",
                                   __FUNCTION__);
  }

  mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
  auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
  error.SetError(err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("::task_info(target_task = 0x%4.4x, "
                  "flavor = TASK_BASIC_INFO, task_info_out => %p, "
                  "task_info_outCnt => %u) failed: %u (%s)",
                  m_task, info, count, error.GetError(), error.AsCString());
    return error;
  }

  Log *verbose_log(
      GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS ));
  if (verbose_log) {
    float user = (float)info->user_time.seconds +
                 (float)info->user_time.microseconds / 1000000.0f;
    float system = (float)info->user_time.seconds +
                   (float)info->user_time.microseconds / 1000000.0f;
    verbose_log->Printf("task_basic_info = { suspend_count = %i, "
                        "virtual_size = 0x%8.8llx, resident_size = "
                        "0x%8.8llx, user_time = %f, system_time = %f }",
                        info->suspend_count, (uint64_t)info->virtual_size,
                        (uint64_t)info->resident_size, user, system);
  }
  return error;
}

Status NativeProcessDarwin::SuspendTask() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  if (m_task == TASK_NULL) {
    error.SetErrorString("task port is null, cannot suspend task");
    if (log)
      log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
                  error.AsCString());
    return error;
  }

  auto mach_err = ::task_suspend(m_task);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail() && log)
    log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);

  return error;
}

Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

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

  if (CanResume()) {
    m_thread_actions = resume_actions;
    error = PrivateResume();
    return error;
  }

  auto state = GetState();
  if (state == eStateRunning) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
                  "running, ignoring...",
                  __FUNCTION__, TaskPortForProcessID(error));
    return error;
  }

  // We can't resume from this state.
  error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
                                 TaskPortForProcessID(error),
                                 StateAsCString(state));
  return error;
}

Status NativeProcessDarwin::Halt() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Detach() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Signal(int signo) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Interrupt() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Kill() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
                                                MemoryRegionInfo &range_info) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf,
                                       size_t size, size_t &bytes_read) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
                                                  size_t size,
                                                  size_t &bytes_read) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
                                        size_t size, size_t &bytes_written) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
                                           lldb::addr_t &addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
  return LLDB_INVALID_ADDRESS;
}

size_t NativeProcessDarwin::UpdateThreads() { return 0; }

bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
  return false;
}

Status NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
                                          bool hardware) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}

Status NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
                                                    FileSpec &file_spec) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
                                               lldb::addr_t &load_addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

// -----------------------------------------------------------------
// NativeProcessProtocol protected interface
// -----------------------------------------------------------------
Status NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
    size_t trap_opcode_size_hint, size_t &actual_opcode_size,
    const uint8_t *&trap_opcode_bytes) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}
