//===-- MachProcess.cpp -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/15/07.
//
//===----------------------------------------------------------------------===//

#include "DNB.h"
#include "MacOSX/CFUtils.h"
#include "SysSignal.h"
#include <dlfcn.h>
#include <inttypes.h>
#include <mach-o/loader.h>
#include <mach/mach.h>
#include <mach/task.h>
#include <pthread.h>
#include <signal.h>
#include <spawn.h>
#include <sys/fcntl.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <uuid/uuid.h>

#include <algorithm>
#include <chrono>
#include <map>
#include <unordered_set>

#include <TargetConditionals.h>
#import <Foundation/Foundation.h>

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

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

#ifndef PLATFORM_BRIDGEOS
#define PLATFORM_BRIDGEOS 5
#endif

#ifndef PLATFORM_MACCATALYST
#define PLATFORM_MACCATALYST 6
#endif

#ifndef PLATFORM_IOSSIMULATOR
#define PLATFORM_IOSSIMULATOR 7
#endif

#ifndef PLATFORM_TVOSSIMULATOR
#define PLATFORM_TVOSSIMULATOR 8
#endif

#ifndef PLATFORM_WATCHOSSIMULATOR
#define PLATFORM_WATCHOSSIMULATOR 9
#endif

#ifndef PLATFORM_DRIVERKIT
#define PLATFORM_DRIVERKIT 10
#endif

#ifndef PLATFORM_VISIONOS
#define PLATFORM_VISIONOS 11
#endif

#ifndef PLATFORM_VISIONOSSIMULATOR
#define PLATFORM_VISIONOSSIMULATOR 12
#endif

#ifdef WITH_SPRINGBOARD

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

#endif // WITH_SPRINGBOARD

#if WITH_CAROUSEL
// For definition of CSLSOpenApplicationOptionForClockKit.
#include <CarouselServices/CSLSOpenApplicationOptions.h>
#endif // WITH_CAROUSEL

#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS)
// This returns a CFRetained pointer to the Bundle ID for app_bundle_path,
// or NULL if there was some problem getting the bundle id.
static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
                                       DNBError &err_str);
#endif

#if defined(WITH_BKS) || defined(WITH_FBS)
#import <Foundation/Foundation.h>
static const int OPEN_APPLICATION_TIMEOUT_ERROR = 111;
typedef void (*SetErrorFunction)(NSInteger, std::string, DNBError &);
typedef bool (*CallOpenApplicationFunction)(NSString *bundleIDNSStr,
                                            NSDictionary *options,
                                            DNBError &error, pid_t *return_pid);

// This function runs the BKSSystemService (or FBSSystemService) method
// openApplication:options:clientPort:withResult,
// messaging the app passed in bundleIDNSStr.
// The function should be run inside of an NSAutoReleasePool.
//
// It will use the "options" dictionary passed in, and fill the error passed in
// if there is an error.
// If return_pid is not NULL, we'll fetch the pid that was made for the
// bundleID.
// If bundleIDNSStr is NULL, then the system application will be messaged.

template <typename OpenFlavor, typename ErrorFlavor,
          ErrorFlavor no_error_enum_value, SetErrorFunction error_function>
static bool CallBoardSystemServiceOpenApplication(NSString *bundleIDNSStr,
                                                  NSDictionary *options,
                                                  DNBError &error,
                                                  pid_t *return_pid) {
  // Now make our systemService:
  OpenFlavor *system_service = [[OpenFlavor alloc] init];

  if (bundleIDNSStr == nil) {
    bundleIDNSStr = [system_service systemApplicationBundleIdentifier];
    if (bundleIDNSStr == nil) {
      // Okay, no system app...
      error.SetErrorString("No system application to message.");
      return false;
    }
  }

  mach_port_t client_port = [system_service createClientPort];
  __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  __block ErrorFlavor open_app_error = no_error_enum_value;
  __block std::string open_app_error_string;
  bool wants_pid = (return_pid != NULL);
  __block pid_t pid_in_block;

  const char *cstr = [bundleIDNSStr UTF8String];
  if (!cstr)
    cstr = "<Unknown Bundle ID>";

  NSString *description = [options description];
  DNBLog("[LaunchAttach] START (%d) templated *Board launcher: app lunch "
         "request for "
         "'%s' - options:\n%s",
         getpid(), cstr, [description UTF8String]);
  [system_service
      openApplication:bundleIDNSStr
              options:options
           clientPort:client_port
           withResult:^(NSError *bks_error) {
             // The system service will cleanup the client port we created for
             // us.
             if (bks_error)
               open_app_error = (ErrorFlavor)[bks_error code];

             if (open_app_error == no_error_enum_value) {
               if (wants_pid) {
                 pid_in_block =
                     [system_service pidForApplication:bundleIDNSStr];
                 DNBLog("[LaunchAttach] In completion handler, got pid for "
                        "bundle id "
                        "'%s', pid: %d.",
                        cstr, pid_in_block);
               } else {
                 DNBLog("[LaunchAttach] In completion handler, launch was "
                        "successful, "
                        "debugserver did not ask for the pid");
               }
             } else {
               const char *error_str =
                   [(NSString *)[bks_error localizedDescription] UTF8String];
               if (error_str) {
                 open_app_error_string = error_str;
                 DNBLogError(
                     "[LaunchAttach] END (%d) In app launch attempt, got error "
                     "localizedDescription '%s'.",
                     getpid(), error_str);
                 const char *obj_desc = 
                      [NSString stringWithFormat:@"%@", bks_error].UTF8String;
                 DNBLogError(
                     "[LaunchAttach] END (%d) In app launch attempt, got error "
                     "NSError object description: '%s'.",
                     getpid(), obj_desc);
               }
               DNBLogThreadedIf(LOG_PROCESS,
                                "In completion handler for send "
                                "event, got error \"%s\"(%ld).",
                                error_str ? error_str : "<unknown error>",
                                (long)open_app_error);
             }

             [system_service release];
             dispatch_semaphore_signal(semaphore);
           }

  ];

  const uint32_t timeout_secs = 30;

  dispatch_time_t timeout =
      dispatch_time(DISPATCH_TIME_NOW, timeout_secs * NSEC_PER_SEC);

  long success = dispatch_semaphore_wait(semaphore, timeout) == 0;

  dispatch_release(semaphore);

  DNBLog("[LaunchAttach] END (%d) templated *Board launcher finished app lunch "
         "request for "
         "'%s'",
         getpid(), cstr);

  if (!success) {
    DNBLogError("[LaunchAttach] END (%d) timed out trying to send "
                "openApplication to %s.",
                getpid(), cstr);
    error.SetError(OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
    error.SetErrorString("timed out trying to launch app");
  } else if (open_app_error != no_error_enum_value) {
    error_function(open_app_error, open_app_error_string, error);
    DNBLogError("[LaunchAttach] END (%d) unable to launch the application with "
                "CFBundleIdentifier '%s' "
                "bks_error = %ld",
                getpid(), cstr, (long)open_app_error);
    success = false;
  } else if (wants_pid) {
    *return_pid = pid_in_block;
    DNBLogThreadedIf(
        LOG_PROCESS,
        "Out of completion handler, pid from block %d and passing out: %d",
        pid_in_block, *return_pid);
  }

  return success;
}
#endif

#if defined(WITH_BKS) || defined(WITH_FBS)
static void SplitEventData(const char *data, std::vector<std::string> &elements)
{
  elements.clear();
  if (!data)
    return;

  const char *start = data;

  while (*start != '\0') {
    const char *token = strchr(start, ':');
    if (!token) {
      elements.push_back(std::string(start));
      return;
    }
    if (token != start)
      elements.push_back(std::string(start, token - start));
    start = ++token;
  }
}
#endif

#ifdef WITH_BKS
#import <Foundation/Foundation.h>
extern "C" {
#import <BackBoardServices/BKSOpenApplicationConstants_Private.h>
#import <BackBoardServices/BKSSystemService_LaunchServices.h>
#import <BackBoardServices/BackBoardServices.h>
}

static bool IsBKSProcess(nub_process_t pid) {
  BKSApplicationStateMonitor *state_monitor =
      [[BKSApplicationStateMonitor alloc] init];
  BKSApplicationState app_state =
      [state_monitor mostElevatedApplicationStateForPID:pid];
  return app_state != BKSApplicationStateUnknown;
}

static void SetBKSError(NSInteger error_code, 
                        std::string error_description, 
                        DNBError &error) {
  error.SetError(error_code, DNBError::BackBoard);
  NSString *err_nsstr = ::BKSOpenApplicationErrorCodeToString(
      (BKSOpenApplicationErrorCode)error_code);
  std::string err_str = "unknown BKS error";
  if (error_description.empty() == false) {
    err_str = error_description;
  } else if (err_nsstr != nullptr) {
    err_str = [err_nsstr UTF8String];
  }
  error.SetErrorString(err_str.c_str());
}

static bool BKSAddEventDataToOptions(NSMutableDictionary *options,
                                     const char *event_data,
                                     DNBError &option_error) {
  std::vector<std::string> values;
  SplitEventData(event_data, values);
  bool found_one = false;
  for (std::string value : values)
  {
      if (value.compare("BackgroundContentFetching") == 0) {
        DNBLog("Setting ActivateForEvent key in options dictionary.");
        NSDictionary *event_details = [NSDictionary dictionary];
        NSDictionary *event_dictionary = [NSDictionary
            dictionaryWithObject:event_details
                          forKey:
                              BKSActivateForEventOptionTypeBackgroundContentFetching];
        [options setObject:event_dictionary
                    forKey:BKSOpenApplicationOptionKeyActivateForEvent];
        found_one = true;
      } else if (value.compare("ActivateSuspended") == 0) {
        DNBLog("Setting ActivateSuspended key in options dictionary.");
        [options setObject:@YES forKey: BKSOpenApplicationOptionKeyActivateSuspended];
        found_one = true;
      } else {
        DNBLogError("Unrecognized event type: %s.  Ignoring.", value.c_str());
        option_error.SetErrorString("Unrecognized event data");
      }
  }
  return found_one;
}

static NSMutableDictionary *BKSCreateOptionsDictionary(
    const char *app_bundle_path, NSMutableArray *launch_argv,
    NSMutableDictionary *launch_envp, NSString *stdio_path, bool disable_aslr,
    const char *event_data) {
  NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
  if (launch_argv != nil)
    [debug_options setObject:launch_argv forKey:BKSDebugOptionKeyArguments];
  if (launch_envp != nil)
    [debug_options setObject:launch_envp forKey:BKSDebugOptionKeyEnvironment];

  [debug_options setObject:stdio_path forKey:BKSDebugOptionKeyStandardOutPath];
  [debug_options setObject:stdio_path
                    forKey:BKSDebugOptionKeyStandardErrorPath];
  [debug_options setObject:[NSNumber numberWithBool:YES]
                    forKey:BKSDebugOptionKeyWaitForDebugger];
  if (disable_aslr)
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:BKSDebugOptionKeyDisableASLR];

  // That will go in the overall dictionary:

  NSMutableDictionary *options = [NSMutableDictionary dictionary];
  [options setObject:debug_options
              forKey:BKSOpenApplicationOptionKeyDebuggingOptions];
  // And there are some other options at the top level in this dictionary:
  [options setObject:[NSNumber numberWithBool:YES]
              forKey:BKSOpenApplicationOptionKeyUnlockDevice];

  DNBError error;
  BKSAddEventDataToOptions(options, event_data, error);

  return options;
}

static CallOpenApplicationFunction BKSCallOpenApplicationFunction =
    CallBoardSystemServiceOpenApplication<
        BKSSystemService, BKSOpenApplicationErrorCode,
        BKSOpenApplicationErrorCodeNone, SetBKSError>;
#endif // WITH_BKS

#ifdef WITH_FBS
#import <Foundation/Foundation.h>
extern "C" {
#import <FrontBoardServices/FBSOpenApplicationConstants_Private.h>
#import <FrontBoardServices/FBSSystemService_LaunchServices.h>
#import <FrontBoardServices/FrontBoardServices.h>
#import <MobileCoreServices/LSResourceProxy.h>
#import <MobileCoreServices/MobileCoreServices.h>
}

#ifdef WITH_BKS
static bool IsFBSProcess(nub_process_t pid) {
  BKSApplicationStateMonitor *state_monitor =
      [[BKSApplicationStateMonitor alloc] init];
  BKSApplicationState app_state =
      [state_monitor mostElevatedApplicationStateForPID:pid];
  return app_state != BKSApplicationStateUnknown;
}
#else
static bool IsFBSProcess(nub_process_t pid) {
  // FIXME: What is the FBS equivalent of BKSApplicationStateMonitor
  return false;
}
#endif

static void SetFBSError(NSInteger error_code, 
                        std::string error_description, 
                        DNBError &error) {
  error.SetError((DNBError::ValueType)error_code, DNBError::FrontBoard);
  NSString *err_nsstr = ::FBSOpenApplicationErrorCodeToString(
      (FBSOpenApplicationErrorCode)error_code);
  std::string err_str = "unknown FBS error";
  if (error_description.empty() == false) {
    err_str = error_description;
  } else if (err_nsstr != nullptr) {
    err_str = [err_nsstr UTF8String];
  }
  error.SetErrorString(err_str.c_str());
}

static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
                                     const char *event_data,
                                     DNBError &option_error) {
  std::vector<std::string> values;
  SplitEventData(event_data, values);
  bool found_one = false;
  for (std::string value : values)
  {
      if (value.compare("BackgroundContentFetching") == 0) {
        DNBLog("Setting ActivateForEvent key in options dictionary.");
        NSDictionary *event_details = [NSDictionary dictionary];
        NSDictionary *event_dictionary = [NSDictionary
            dictionaryWithObject:event_details
                          forKey:
                              FBSActivateForEventOptionTypeBackgroundContentFetching];
        [options setObject:event_dictionary
                    forKey:FBSOpenApplicationOptionKeyActivateForEvent];
        found_one = true;
      } else if (value.compare("ActivateSuspended") == 0) {
        DNBLog("Setting ActivateSuspended key in options dictionary.");
        [options setObject:@YES forKey: FBSOpenApplicationOptionKeyActivateSuspended];
        found_one = true;
#if WITH_CAROUSEL
      } else if (value.compare("WatchComplicationLaunch") == 0) {
        DNBLog("Setting FBSOpenApplicationOptionKeyActivateSuspended key in options dictionary.");
        [options setObject:@YES forKey: CSLSOpenApplicationOptionForClockKit];
        found_one = true;
#endif // WITH_CAROUSEL
      } else {
        DNBLogError("Unrecognized event type: %s.  Ignoring.", value.c_str());
        option_error.SetErrorString("Unrecognized event data.");
      }
  }
  return found_one;
}

static NSMutableDictionary *
FBSCreateOptionsDictionary(const char *app_bundle_path,
                           NSMutableArray *launch_argv,
                           NSDictionary *launch_envp, NSString *stdio_path,
                           bool disable_aslr, const char *event_data) {
  NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];

  if (launch_argv != nil)
    [debug_options setObject:launch_argv forKey:FBSDebugOptionKeyArguments];
  if (launch_envp != nil)
    [debug_options setObject:launch_envp forKey:FBSDebugOptionKeyEnvironment];

  [debug_options setObject:stdio_path forKey:FBSDebugOptionKeyStandardOutPath];
  [debug_options setObject:stdio_path
                    forKey:FBSDebugOptionKeyStandardErrorPath];
  [debug_options setObject:[NSNumber numberWithBool:YES]
                    forKey:FBSDebugOptionKeyWaitForDebugger];
  if (disable_aslr)
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:FBSDebugOptionKeyDisableASLR];

  // That will go in the overall dictionary:

  NSMutableDictionary *options = [NSMutableDictionary dictionary];
  [options setObject:debug_options
              forKey:FBSOpenApplicationOptionKeyDebuggingOptions];
  // And there are some other options at the top level in this dictionary:
  [options setObject:[NSNumber numberWithBool:YES]
              forKey:FBSOpenApplicationOptionKeyUnlockDevice];
  [options setObject:[NSNumber numberWithBool:YES]
              forKey:FBSOpenApplicationOptionKeyPromptUnlockDevice];

  // We have to get the "sequence ID & UUID" for this app bundle path and send
  // them to FBS:

  NSURL *app_bundle_url =
      [NSURL fileURLWithPath:[NSString stringWithUTF8String:app_bundle_path]
                 isDirectory:YES];
  LSApplicationProxy *app_proxy =
      [LSApplicationProxy applicationProxyForBundleURL:app_bundle_url];
  if (app_proxy) {
    DNBLog("Sending AppProxy info: sequence no: %lu, GUID: %s.",
           app_proxy.sequenceNumber,
           [app_proxy.cacheGUID.UUIDString UTF8String]);
    [options
        setObject:[NSNumber numberWithUnsignedInteger:app_proxy.sequenceNumber]
           forKey:FBSOpenApplicationOptionKeyLSSequenceNumber];
    [options setObject:app_proxy.cacheGUID.UUIDString
                forKey:FBSOpenApplicationOptionKeyLSCacheGUID];
  }

  DNBError error;
  FBSAddEventDataToOptions(options, event_data, error);

  return options;
}
static CallOpenApplicationFunction FBSCallOpenApplicationFunction =
    CallBoardSystemServiceOpenApplication<
        FBSSystemService, FBSOpenApplicationErrorCode,
        FBSOpenApplicationErrorCodeNone, SetFBSError>;
#endif // WITH_FBS

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

#ifndef MACH_PROCESS_USE_POSIX_SPAWN
#define MACH_PROCESS_USE_POSIX_SPAWN 1
#endif

#ifndef _POSIX_SPAWN_DISABLE_ASLR
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
#endif

MachProcess::MachProcess()
    : m_pid(0), m_cpu_type(0), m_child_stdin(-1), m_child_stdout(-1),
      m_child_stderr(-1), m_path(), m_args(), m_task(this),
      m_flags(eMachProcessFlagsNone), m_stdio_thread(0), m_stdio_mutex(),
      m_stdout_data(), m_profile_enabled(false), m_profile_interval_usec(0),
      m_profile_thread(0), m_profile_data_mutex(), m_profile_data(),
      m_profile_events(0, eMachProcessProfileCancel), m_thread_actions(),
      m_exception_messages(), m_exception_and_signal_mutex(), m_thread_list(),
      m_activities(), m_state(eStateUnloaded), m_state_mutex(),
      m_events(0, kAllEventsMask), m_private_events(0, kAllEventsMask),
      m_breakpoints(), m_watchpoints(), m_name_to_addr_callback(NULL),
      m_name_to_addr_baton(NULL), m_image_infos_callback(NULL),
      m_image_infos_baton(NULL), m_sent_interrupt_signo(0),
      m_auto_resume_signo(0), m_did_exec(false),
      m_dyld_process_info_create(nullptr),
      m_dyld_process_create_for_task(nullptr),
      m_dyld_process_snapshot_create_for_process(nullptr),
      m_dyld_process_snapshot_get_shared_cache(nullptr),
      m_dyld_shared_cache_for_each_file(nullptr),
      m_dyld_shared_cache_get_mapped_size(nullptr),
      m_dyld_process_snapshot_dispose(nullptr), m_dyld_process_dispose(nullptr),
      m_dyld_process_info_for_each_image(nullptr),
      m_dyld_process_info_release(nullptr),
      m_dyld_process_info_get_cache(nullptr),
      m_dyld_process_info_get_state(nullptr),
      m_dyld_shared_cache_file_path(nullptr) {
  m_dyld_process_info_create =
      (void *(*)(task_t task, uint64_t timestamp, kern_return_t * kernelError))
          dlsym(RTLD_DEFAULT, "_dyld_process_info_create");

  m_dyld_process_create_for_task =
      (void *(*)(task_read_t, kern_return_t *))dlsym(
          RTLD_DEFAULT, "dyld_process_create_for_task");
  m_dyld_process_snapshot_create_for_process =
      (void *(*)(void *, kern_return_t *))dlsym(
          RTLD_DEFAULT, "dyld_process_snapshot_create_for_process");
  m_dyld_process_snapshot_get_shared_cache = (void *(*)(void *))dlsym(
      RTLD_DEFAULT, "dyld_process_snapshot_get_shared_cache");
  m_dyld_shared_cache_for_each_file =
      (void (*)(void *, void (^)(const char *)))dlsym(
          RTLD_DEFAULT, "dyld_shared_cache_for_each_file");
  m_dyld_shared_cache_get_mapped_size = (uint64_t(*)(void *))dlsym(
      RTLD_DEFAULT, "dyld_shared_cache_get_mapped_size");
  m_dyld_process_snapshot_dispose =
      (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_snapshot_dispose");
  m_dyld_process_dispose =
      (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_dispose");
  m_dyld_process_info_for_each_image =
      (void (*)(void *info, void (^)(uint64_t machHeaderAddress,
                                     const uuid_t uuid, const char *path)))
          dlsym(RTLD_DEFAULT, "_dyld_process_info_for_each_image");
  m_dyld_process_info_release =
      (void (*)(void *info))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");
  m_dyld_process_info_get_cache = (void (*)(void *info, void *cacheInfo))dlsym(
      RTLD_DEFAULT, "_dyld_process_info_get_cache");
  m_dyld_process_info_get_platform = (uint32_t (*)(void *info))dlsym(
      RTLD_DEFAULT, "_dyld_process_info_get_platform");
  m_dyld_process_info_get_state = (void (*)(void *info, void *stateInfo))dlsym(
      RTLD_DEFAULT, "_dyld_process_info_get_state");
  m_dyld_shared_cache_file_path =
      (const char *(*)())dlsym(RTLD_DEFAULT, "dyld_shared_cache_file_path");

  DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
}

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

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

nub_state_t MachProcess::GetState() {
  // If any other threads access this we will need a mutex for it
  std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
  return m_state;
}

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

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

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

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

nub_thread_t
MachProcess::GetThreadIDForMachPortNumber(thread_t mach_port_number) const {
  return m_thread_list.GetThreadIDByMachPortNumber(mach_port_number);
}

nub_bool_t MachProcess::SyncThreadState(nub_thread_t tid) {
  MachThreadSP thread_sp(m_thread_list.GetThreadByID(tid));
  if (!thread_sp)
    return false;
  kern_return_t kret = ::thread_abort_safely(thread_sp->MachPortNumber());
  DNBLogThreadedIf(LOG_THREAD, "thread = 0x%8.8" PRIx32
                               " calling thread_abort_safely (tid) => %u "
                               "(GetGPRState() for stop_count = %u)",
                   thread_sp->MachPortNumber(), kret,
                   thread_sp->Process()->StopCount());

  if (kret == KERN_SUCCESS)
    return true;
  else
    return false;
}

ThreadInfo::QoS MachProcess::GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd,
                                             uint64_t dti_qos_class_index) {
  return m_thread_list.GetRequestedQoS(tid, tsd, dti_qos_class_index);
}

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

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

nub_addr_t MachProcess::GetTSDAddressForThread(
    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) {
  return m_thread_list.GetTSDAddressForThread(
      tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset,
      plo_pthread_tsd_entry_size);
}

MachProcess::DeploymentInfo
MachProcess::GetDeploymentInfo(const struct load_command &lc,
                               uint64_t load_command_address,
                               bool is_executable) {
  DeploymentInfo info;
  uint32_t cmd = lc.cmd & ~LC_REQ_DYLD;

  // Handle the older LC_VERSION load commands, which don't
  // distinguish between simulator and real hardware.
  auto handle_version_min = [&](char platform) {
    struct version_min_command vers_cmd;
    if (ReadMemory(load_command_address, sizeof(struct version_min_command),
                   &vers_cmd) != sizeof(struct version_min_command))
      return;
    info.platform = platform;
    info.major_version = vers_cmd.version >> 16;
    info.minor_version = (vers_cmd.version >> 8) & 0xffu;
    info.patch_version = vers_cmd.version & 0xffu;

    // Disambiguate legacy simulator platforms.
#if (defined(__x86_64__) || defined(__i386__))
    // If we are running on Intel macOS, it is safe to assume this is
    // really a back-deploying simulator binary.
    switch (info.platform) {
    case PLATFORM_IOS:
      info.platform = PLATFORM_IOSSIMULATOR;
      break;
    case PLATFORM_TVOS:
      info.platform = PLATFORM_TVOSSIMULATOR;
      break;
    case PLATFORM_WATCHOS:
      info.platform = PLATFORM_WATCHOSSIMULATOR;
      break;
    }
#else
    // On an Apple Silicon macOS host, there is no ambiguity. The only
    // binaries that use legacy load commands are back-deploying
    // native iOS binaries. All simulator binaries use the newer,
    // unambiguous LC_BUILD_VERSION load commands.
#endif
  };

  switch (cmd) {
  case LC_VERSION_MIN_IPHONEOS:
    handle_version_min(PLATFORM_IOS);
    break;
  case LC_VERSION_MIN_MACOSX:
    handle_version_min(PLATFORM_MACOS);
    break;
  case LC_VERSION_MIN_TVOS:
    handle_version_min(PLATFORM_TVOS);
    break;
  case LC_VERSION_MIN_WATCHOS:
    handle_version_min(PLATFORM_WATCHOS);
    break;
#if defined(LC_BUILD_VERSION)
  case LC_BUILD_VERSION: {
    struct build_version_command build_vers;
    if (ReadMemory(load_command_address, sizeof(struct build_version_command),
                   &build_vers) != sizeof(struct build_version_command))
      break;
    info.platform = build_vers.platform;
    info.major_version = build_vers.minos >> 16;
    info.minor_version = (build_vers.minos >> 8) & 0xffu;
    info.patch_version = build_vers.minos & 0xffu;
    break;
  }
#endif
  }

  // The xctest binary is a pure macOS binary but is launched with
  // DYLD_FORCE_PLATFORM=6. In that case, force the platform to
  // macCatalyst and use the macCatalyst version of the host OS
  // instead of the macOS deployment target.
  if (is_executable && GetPlatform() == PLATFORM_MACCATALYST) {
    info.platform = PLATFORM_MACCATALYST;
    std::string catalyst_version = GetMacCatalystVersionString();
    const char *major = catalyst_version.c_str();
    char *minor = nullptr;
    char *patch = nullptr;
    info.major_version = std::strtoul(major, &minor, 10);
    info.minor_version = 0;
    info.patch_version = 0;
    if (minor && *minor == '.') {
      info.minor_version = std::strtoul(++minor, &patch, 10);
      if (patch && *patch == '.')
        info.patch_version = std::strtoul(++patch, nullptr, 10);
    }
  }

  return info;
}

std::optional<std::string>
MachProcess::GetPlatformString(unsigned char platform) {
  switch (platform) {
  case PLATFORM_MACOS:
    return "macosx";
  case PLATFORM_MACCATALYST:
    return "maccatalyst";
  case PLATFORM_IOS:
    return "ios";
  case PLATFORM_IOSSIMULATOR:
    return "iossimulator";
  case PLATFORM_TVOS:
    return "tvos";
  case PLATFORM_TVOSSIMULATOR:
    return "tvossimulator";
  case PLATFORM_WATCHOS:
    return "watchos";
  case PLATFORM_WATCHOSSIMULATOR:
    return "watchossimulator";
  case PLATFORM_BRIDGEOS:
    return "bridgeos";
  case PLATFORM_DRIVERKIT:
    return "driverkit";
  case PLATFORM_VISIONOS:
    return "xros";
  case PLATFORM_VISIONOSSIMULATOR:
    return "xrossimulator";
  default:
    DNBLogError("Unknown platform %u found for one binary", platform);
    return std::nullopt;
  }
}

static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
  if (magic != MH_MAGIC && magic != MH_CIGAM && magic != MH_MAGIC_64 &&
      magic != MH_CIGAM_64)
    return false;
  if (cputype != CPU_TYPE_I386 && cputype != CPU_TYPE_X86_64 &&
      cputype != CPU_TYPE_ARM && cputype != CPU_TYPE_ARM64 &&
      cputype != CPU_TYPE_ARM64_32)
    return false;
  return true;
}

// Given an address, read the mach-o header and load commands out of memory to
// fill in
// the mach_o_information "inf" object.
//
// Returns false if there was an error in reading this mach-o file header/load
// commands.

bool MachProcess::GetMachOInformationFromMemory(
    uint32_t dyld_platform, nub_addr_t mach_o_header_addr, int wordsize,
    struct mach_o_information &inf) {
  uint64_t load_cmds_p;

  if (wordsize == 4) {
    struct mach_header header;
    if (ReadMemory(mach_o_header_addr, sizeof(struct mach_header), &header) !=
        sizeof(struct mach_header)) {
      return false;
    }
    if (!mach_header_validity_test(header.magic, header.cputype))
      return false;

    load_cmds_p = mach_o_header_addr + sizeof(struct mach_header);
    inf.mach_header.magic = header.magic;
    inf.mach_header.cputype = header.cputype;
    // high byte of cpusubtype is used for "capability bits", v.
    // CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
    inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
    inf.mach_header.filetype = header.filetype;
    inf.mach_header.ncmds = header.ncmds;
    inf.mach_header.sizeofcmds = header.sizeofcmds;
    inf.mach_header.flags = header.flags;
  } else {
    struct mach_header_64 header;
    if (ReadMemory(mach_o_header_addr, sizeof(struct mach_header_64),
                   &header) != sizeof(struct mach_header_64)) {
      return false;
    }
    if (!mach_header_validity_test(header.magic, header.cputype))
      return false;
    load_cmds_p = mach_o_header_addr + sizeof(struct mach_header_64);
    inf.mach_header.magic = header.magic;
    inf.mach_header.cputype = header.cputype;
    // high byte of cpusubtype is used for "capability bits", v.
    // CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
    inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
    inf.mach_header.filetype = header.filetype;
    inf.mach_header.ncmds = header.ncmds;
    inf.mach_header.sizeofcmds = header.sizeofcmds;
    inf.mach_header.flags = header.flags;
  }
  for (uint32_t j = 0; j < inf.mach_header.ncmds; j++) {
    struct load_command lc;
    if (ReadMemory(load_cmds_p, sizeof(struct load_command), &lc) !=
        sizeof(struct load_command)) {
      return false;
    }
    if (lc.cmd == LC_SEGMENT) {
      struct segment_command seg;
      if (ReadMemory(load_cmds_p, sizeof(struct segment_command), &seg) !=
          sizeof(struct segment_command)) {
        return false;
      }
      struct mach_o_segment this_seg;
      char name[17];
      ::memset(name, 0, sizeof(name));
      memcpy(name, seg.segname, sizeof(seg.segname));
      this_seg.name = name;
      this_seg.vmaddr = seg.vmaddr;
      this_seg.vmsize = seg.vmsize;
      this_seg.fileoff = seg.fileoff;
      this_seg.filesize = seg.filesize;
      this_seg.maxprot = seg.maxprot;
      this_seg.initprot = seg.initprot;
      this_seg.nsects = seg.nsects;
      this_seg.flags = seg.flags;
      inf.segments.push_back(this_seg);
      if (this_seg.name == "ExecExtraSuspend")
        m_task.TaskWillExecProcessesSuspended();
    }
    if (lc.cmd == LC_SEGMENT_64) {
      struct segment_command_64 seg;
      if (ReadMemory(load_cmds_p, sizeof(struct segment_command_64), &seg) !=
          sizeof(struct segment_command_64)) {
        return false;
      }
      struct mach_o_segment this_seg;
      char name[17];
      ::memset(name, 0, sizeof(name));
      memcpy(name, seg.segname, sizeof(seg.segname));
      this_seg.name = name;
      this_seg.vmaddr = seg.vmaddr;
      this_seg.vmsize = seg.vmsize;
      this_seg.fileoff = seg.fileoff;
      this_seg.filesize = seg.filesize;
      this_seg.maxprot = seg.maxprot;
      this_seg.initprot = seg.initprot;
      this_seg.nsects = seg.nsects;
      this_seg.flags = seg.flags;
      inf.segments.push_back(this_seg);
      if (this_seg.name == "ExecExtraSuspend")
        m_task.TaskWillExecProcessesSuspended();
    }
    if (lc.cmd == LC_UUID) {
      struct uuid_command uuidcmd;
      if (ReadMemory(load_cmds_p, sizeof(struct uuid_command), &uuidcmd) ==
          sizeof(struct uuid_command))
        uuid_copy(inf.uuid, uuidcmd.uuid);
    }
    if (DeploymentInfo deployment_info = GetDeploymentInfo(
            lc, load_cmds_p, inf.mach_header.filetype == MH_EXECUTE)) {
      std::optional<std::string> lc_platform =
          GetPlatformString(deployment_info.platform);
      if (dyld_platform != PLATFORM_MACCATALYST &&
          inf.min_version_os_name == "macosx") {
        // macCatalyst support.
        //
        // This the special case of "zippered" frameworks that have both
        // a PLATFORM_MACOS and a PLATFORM_MACCATALYST load command.
        //
        // When we are in this block, this is a binary with both
        // PLATFORM_MACOS and PLATFORM_MACCATALYST load commands and
        // the process is not running as PLATFORM_MACCATALYST. Stick
        // with the "macosx" load command that we've already
        // processed, ignore this one, which is presumed to be a
        // PLATFORM_MACCATALYST one.
      } else {
        inf.min_version_os_name = lc_platform.value_or("");
        inf.min_version_os_version = "";
        inf.min_version_os_version +=
            std::to_string(deployment_info.major_version);
        inf.min_version_os_version += ".";
        inf.min_version_os_version +=
            std::to_string(deployment_info.minor_version);
        if (deployment_info.patch_version != 0) {
          inf.min_version_os_version += ".";
          inf.min_version_os_version +=
              std::to_string(deployment_info.patch_version);
        }
      }
    }

    load_cmds_p += lc.cmdsize;
  }
  return true;
}

// Given completely filled in array of binary_image_information structures,
// create a JSONGenerator object
// with all the details we want to send to lldb.
JSONGenerator::ObjectSP MachProcess::FormatDynamicLibrariesIntoJSON(
    const std::vector<struct binary_image_information> &image_infos,
    DNBBinaryInformationLevel info_level) {

  JSONGenerator::ArraySP image_infos_array_sp(new JSONGenerator::Array());

  const size_t image_count = image_infos.size();

  for (size_t i = 0; i < image_count; i++) {
    // If we should report the Mach-O header and load commands,
    // and those were unreadable, don't report anything about this
    // binary.
    if (info_level == eBinaryInformationLevelFull &&
        !image_infos[i].is_valid_mach_header)
      continue;
    JSONGenerator::DictionarySP image_info_dict_sp(
        new JSONGenerator::Dictionary());
    image_info_dict_sp->AddIntegerItem("load_address",
                                       image_infos[i].load_address);
    if (info_level == eBinaryInformationLevelAddrOnly) {
      image_infos_array_sp->AddItem(image_info_dict_sp);
      continue;
    }

    image_info_dict_sp->AddStringItem("pathname", image_infos[i].filename);
    if (info_level == eBinaryInformationLevelAddrName) {
      image_infos_array_sp->AddItem(image_info_dict_sp);
      continue;
    }

    uuid_string_t uuidstr;
    uuid_unparse_upper(image_infos[i].macho_info.uuid, uuidstr);
    image_info_dict_sp->AddStringItem("uuid", uuidstr);
    if (info_level == eBinaryInformationLevelAddrNameUUID) {
      image_infos_array_sp->AddItem(image_info_dict_sp);
      continue;
    }

    if (!image_infos[i].macho_info.min_version_os_name.empty() &&
        !image_infos[i].macho_info.min_version_os_version.empty()) {
      image_info_dict_sp->AddStringItem(
          "min_version_os_name", image_infos[i].macho_info.min_version_os_name);
      image_info_dict_sp->AddStringItem(
          "min_version_os_sdk",
          image_infos[i].macho_info.min_version_os_version);
    }

    JSONGenerator::DictionarySP mach_header_dict_sp(
        new JSONGenerator::Dictionary());
    mach_header_dict_sp->AddIntegerItem(
        "magic", image_infos[i].macho_info.mach_header.magic);
    mach_header_dict_sp->AddIntegerItem(
        "cputype", (uint32_t)image_infos[i].macho_info.mach_header.cputype);
    mach_header_dict_sp->AddIntegerItem(
        "cpusubtype",
        (uint32_t)image_infos[i].macho_info.mach_header.cpusubtype);
    mach_header_dict_sp->AddIntegerItem(
        "filetype", image_infos[i].macho_info.mach_header.filetype);
    mach_header_dict_sp->AddIntegerItem ("flags", 
                         image_infos[i].macho_info.mach_header.flags);

    //          DynamicLoaderMacOSX doesn't currently need these fields, so
    //          don't send them.
    //            mach_header_dict_sp->AddIntegerItem ("ncmds",
    //            image_infos[i].macho_info.mach_header.ncmds);
    //            mach_header_dict_sp->AddIntegerItem ("sizeofcmds",
    //            image_infos[i].macho_info.mach_header.sizeofcmds);
    image_info_dict_sp->AddItem("mach_header", mach_header_dict_sp);

    JSONGenerator::ArraySP segments_sp(new JSONGenerator::Array());
    for (size_t j = 0; j < image_infos[i].macho_info.segments.size(); j++) {
      JSONGenerator::DictionarySP segment_sp(new JSONGenerator::Dictionary());
      segment_sp->AddStringItem("name",
                                image_infos[i].macho_info.segments[j].name);
      segment_sp->AddIntegerItem("vmaddr",
                                 image_infos[i].macho_info.segments[j].vmaddr);
      segment_sp->AddIntegerItem("vmsize",
                                 image_infos[i].macho_info.segments[j].vmsize);
      segment_sp->AddIntegerItem("fileoff",
                                 image_infos[i].macho_info.segments[j].fileoff);
      segment_sp->AddIntegerItem(
          "filesize", image_infos[i].macho_info.segments[j].filesize);
      segment_sp->AddIntegerItem("maxprot",
                                 image_infos[i].macho_info.segments[j].maxprot);

      //              DynamicLoaderMacOSX doesn't currently need these fields,
      //              so don't send them.
      //                segment_sp->AddIntegerItem ("initprot",
      //                image_infos[i].macho_info.segments[j].initprot);
      //                segment_sp->AddIntegerItem ("nsects",
      //                image_infos[i].macho_info.segments[j].nsects);
      //                segment_sp->AddIntegerItem ("flags",
      //                image_infos[i].macho_info.segments[j].flags);
      segments_sp->AddItem(segment_sp);
    }
    image_info_dict_sp->AddItem("segments", segments_sp);

    image_infos_array_sp->AddItem(image_info_dict_sp);
  }

  JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
  reply_sp->AddItem("images", image_infos_array_sp);

  return reply_sp;
}

/// From dyld SPI header dyld_process_info.h
typedef void *dyld_process_info;
struct dyld_process_cache_info {
  /// UUID of cache used by process.
  uuid_t cacheUUID;
  /// Load address of dyld shared cache.
  uint64_t cacheBaseAddress;
  /// Process is running without a dyld cache.
  bool noCache;
  /// Process is using a private copy of its dyld cache.
  bool privateCache;
};

uint32_t MachProcess::GetPlatform() {
  if (m_platform == 0)
    m_platform = MachProcess::GetProcessPlatformViaDYLDSPI();
  return m_platform;
}

uint32_t MachProcess::GetProcessPlatformViaDYLDSPI() {
  kern_return_t kern_ret;
  uint32_t platform = 0;
  if (m_dyld_process_info_create) {
    dyld_process_info info =
        m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
    if (info) {
      if (m_dyld_process_info_get_platform)
        platform = m_dyld_process_info_get_platform(info);
      m_dyld_process_info_release(info);
    }
  }
  return platform;
}

void MachProcess::GetAllLoadedBinariesViaDYLDSPI(
    std::vector<struct binary_image_information> &image_infos) {
  kern_return_t kern_ret;
  if (m_dyld_process_info_create) {
    dyld_process_info info =
        m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
    if (info) {
      // There's a bug in the interaction between dyld and older dyld_sim's
      // (e.g. from the iOS 15 simulator) that causes dyld to report the same
      // binary twice.  We use this set to eliminate the duplicates.
      __block std::unordered_set<uint64_t> seen_header_addrs;
      m_dyld_process_info_for_each_image(
          info,
          ^(uint64_t mach_header_addr, const uuid_t uuid, const char *path) {
            auto res_pair = seen_header_addrs.insert(mach_header_addr);
            if (!res_pair.second)
              return;
            struct binary_image_information image;
            image.filename = path;
            uuid_copy(image.macho_info.uuid, uuid);
            image.load_address = mach_header_addr;
            image_infos.push_back(image);
          });
      m_dyld_process_info_release(info);
    }
  }
}

// Fetch information about all shared libraries using the dyld SPIs that exist
// in
// macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
JSONGenerator::ObjectSP
MachProcess::GetAllLoadedLibrariesInfos(nub_process_t pid,
                                        DNBBinaryInformationLevel info_level) {

  int pointer_size = GetInferiorAddrSize(pid);
  std::vector<struct binary_image_information> image_infos;
  GetAllLoadedBinariesViaDYLDSPI(image_infos);
  if (info_level == eBinaryInformationLevelFull) {
    uint32_t platform = GetPlatform();
    const size_t image_count = image_infos.size();
    for (size_t i = 0; i < image_count; i++) {
      if (GetMachOInformationFromMemory(platform, image_infos[i].load_address,
                                        pointer_size,
                                        image_infos[i].macho_info)) {
        image_infos[i].is_valid_mach_header = true;
      }
    }
  }
  return FormatDynamicLibrariesIntoJSON(image_infos, info_level);
}

std::optional<std::pair<cpu_type_t, cpu_subtype_t>>
MachProcess::GetMainBinaryCPUTypes(nub_process_t pid) {
  int pointer_size = GetInferiorAddrSize(pid);
  std::vector<struct binary_image_information> image_infos;
  GetAllLoadedBinariesViaDYLDSPI(image_infos);
  uint32_t platform = GetPlatform();
  for (auto &image_info : image_infos)
    if (GetMachOInformationFromMemory(platform, image_info.load_address,
                                      pointer_size, image_info.macho_info))
      if (image_info.macho_info.mach_header.filetype == MH_EXECUTE)
        return {
            {static_cast<cpu_type_t>(image_info.macho_info.mach_header.cputype),
             static_cast<cpu_subtype_t>(
                 image_info.macho_info.mach_header.cpusubtype)}};
  return {};
}

// Fetch information about the shared libraries at the given load addresses
// using the
// dyld SPIs that exist in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
JSONGenerator::ObjectSP MachProcess::GetLibrariesInfoForAddresses(
    nub_process_t pid, DNBBinaryInformationLevel info_level,
    std::vector<uint64_t> &macho_addresses) {

  int pointer_size = GetInferiorAddrSize(pid);

  // Collect the list of all binaries that dyld knows about in
  // the inferior process.
  std::vector<struct binary_image_information> all_image_infos;
  GetAllLoadedBinariesViaDYLDSPI(all_image_infos);
  uint32_t platform = GetPlatform();

  std::vector<struct binary_image_information> image_infos;
  const size_t macho_addresses_count = macho_addresses.size();
  const size_t all_image_infos_count = all_image_infos.size();

  for (size_t i = 0; i < macho_addresses_count; i++) {
    bool found_matching_entry = false;
    for (size_t j = 0; j < all_image_infos_count; j++) {
      if (all_image_infos[j].load_address == macho_addresses[i]) {
        image_infos.push_back(all_image_infos[j]);
        found_matching_entry = true;
      }
    }
    if (!found_matching_entry) {
      // dyld doesn't think there is a binary at this address,
      // but maybe there isn't a binary YET - let's look in memory
      // for a proper mach-o header etc and return what we can.
      // We will have an empty filename for the binary (because dyld
      // doesn't know about it yet) but we can read all of the mach-o
      // load commands from memory directly.
      struct binary_image_information entry;
      entry.load_address = macho_addresses[i];
      image_infos.push_back(entry);
    }
  }

    const size_t image_infos_count = image_infos.size();
    for (size_t i = 0; i < image_infos_count; i++) {
      if (GetMachOInformationFromMemory(platform, image_infos[i].load_address,
                                        pointer_size,
                                        image_infos[i].macho_info)) {
        image_infos[i].is_valid_mach_header = true;
      }
    }
    return FormatDynamicLibrariesIntoJSON(image_infos, info_level);
}

bool MachProcess::GetDebugserverSharedCacheInfo(
    uuid_t &uuid, std::string &shared_cache_path) {
  uuid_clear(uuid);
  shared_cache_path.clear();

  if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
    kern_return_t kern_ret;
    dyld_process_info info =
        m_dyld_process_info_create(mach_task_self(), 0, &kern_ret);
    if (info) {
      struct dyld_process_cache_info shared_cache_info;
      m_dyld_process_info_get_cache(info, &shared_cache_info);
      uuid_copy(uuid, shared_cache_info.cacheUUID);
      m_dyld_process_info_release(info);
    }
  }
  if (m_dyld_shared_cache_file_path) {
    const char *cache_path = m_dyld_shared_cache_file_path();
    if (cache_path)
      shared_cache_path = cache_path;
  }
  if (!uuid_is_null(uuid))
    return true;
  return false;
}

bool MachProcess::GetInferiorSharedCacheFilepathAndSize(
    std::string &inferior_sc_path, uint64_t &size) {
  inferior_sc_path.clear();

  if (!m_dyld_process_create_for_task ||
      !m_dyld_process_snapshot_create_for_process ||
      !m_dyld_process_snapshot_get_shared_cache ||
      !m_dyld_shared_cache_for_each_file || !m_dyld_process_snapshot_dispose ||
      !m_dyld_shared_cache_get_mapped_size || !m_dyld_process_dispose)
    return false;

  __block std::string sc_path;
  kern_return_t kr;
  void *process = m_dyld_process_create_for_task(m_task.TaskPort(), &kr);
  if (kr != KERN_SUCCESS)
    return false;
  void *snapshot = m_dyld_process_snapshot_create_for_process(process, &kr);
  if (kr != KERN_SUCCESS)
    return false;
  void *cache = m_dyld_process_snapshot_get_shared_cache(snapshot);

  // The shared cache is a collection of files on disk, this callback
  // will iterate over all of them.
  // The first filepath provided is the base filename of the cache.
  __block bool done = false;
  m_dyld_shared_cache_for_each_file(cache, ^(const char *path) {
    if (done) {
      return;
    }
    done = true;
    sc_path = path;
  });
  size = m_dyld_shared_cache_get_mapped_size(cache);

  m_dyld_process_snapshot_dispose(snapshot);
  m_dyld_process_dispose(process);

  inferior_sc_path = sc_path;
  if (!sc_path.empty())
    return true;
  return false;
}

// From dyld's internal dyld_process_info.h:

JSONGenerator::ObjectSP
MachProcess::GetInferiorSharedCacheInfo(nub_process_t pid) {
  JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());

  uuid_t inferior_sc_uuid;
  if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
    kern_return_t kern_ret;
    dyld_process_info info =
        m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
    if (info) {
      struct dyld_process_cache_info shared_cache_info;
      m_dyld_process_info_get_cache(info, &shared_cache_info);

      reply_sp->AddIntegerItem("shared_cache_base_address",
                               shared_cache_info.cacheBaseAddress);

      uuid_string_t uuidstr;
      uuid_unparse_upper(shared_cache_info.cacheUUID, uuidstr);
      uuid_copy(inferior_sc_uuid, shared_cache_info.cacheUUID);
      reply_sp->AddStringItem("shared_cache_uuid", uuidstr);

      reply_sp->AddBooleanItem("no_shared_cache", shared_cache_info.noCache);
      reply_sp->AddBooleanItem("shared_cache_private_cache",
                               shared_cache_info.privateCache);

      m_dyld_process_info_release(info);
    }
  }


  // Use SPI that are only available on newer OSes to fetch the
  // filepath of the shared cache of the inferior, if available.
  std::string inferior_sc_path;
  uint64_t size;
  if (GetInferiorSharedCacheFilepathAndSize(inferior_sc_path, size)) {
    reply_sp->AddStringItem("shared_cache_path", inferior_sc_path);
    reply_sp->AddIntegerItem("shared_cache_size", size);
  } else {
    // If debugserver and the inferior are have the same cache UUID,
    // use the simple call to get the filepath to debugserver's shared
    // cache, return that.  Can't get the shared cache size this way,
    // currently.
    uuid_t debugserver_sc_uuid;
    std::string debugserver_sc_path;
    if (GetDebugserverSharedCacheInfo(debugserver_sc_uuid,
                                      debugserver_sc_path)) {
      if (uuid_compare(inferior_sc_uuid, debugserver_sc_uuid) == 0 &&
          !debugserver_sc_path.empty()) {
        reply_sp->AddStringItem("shared_cache_path", debugserver_sc_path);
      }
    }
  }

  return reply_sp;
}

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

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

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

bool MachProcess::GetThreadStoppedReason(nub_thread_t tid,
                                         struct DNBThreadStopInfo *stop_info) {
  if (m_thread_list.GetThreadStoppedReason(tid, stop_info)) {
    if (m_did_exec)
      stop_info->reason = eStopTypeExec;
    if (stop_info->reason == eStopTypeWatchpoint)
      RefineWatchpointStopInfo(tid, stop_info);
    return true;
  }
  return false;
}

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

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

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

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

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

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

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

  // Scope for mutex locker
  {
    std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
    const nub_state_t old_state = m_state;

    if (old_state == eStateExited) {
      DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SetState(%s) ignoring new "
                                    "state since current state is exited",
                       DNBStateAsString(new_state));
    } else if (old_state == new_state) {
      DNBLogThreadedIf(
          LOG_PROCESS,
          "MachProcess::SetState(%s) ignoring redundant state change...",
          DNBStateAsString(new_state));
    } else {
      if (NUB_STATE_IS_STOPPED(new_state))
        event_mask = eEventProcessStoppedStateChanged;
      else
        event_mask = eEventProcessRunningStateChanged;

      DNBLogThreadedIf(
          LOG_PROCESS, "MachProcess::SetState(%s) upating state (previous "
                       "state was %s), event_mask = 0x%8.8x",
          DNBStateAsString(new_state), DNBStateAsString(old_state), event_mask);

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

  if (event_mask != 0) {
    m_events.SetEvents(event_mask);
    m_private_events.SetEvents(event_mask);
    if (event_mask == eEventProcessStoppedStateChanged)
      m_private_events.ResetEvents(eEventProcessRunningStateChanged);
    else
      m_private_events.ResetEvents(eEventProcessStoppedStateChanged);

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

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

  m_task.Clear();
  m_platform = 0;
  // Now clear out all member variables
  m_pid = INVALID_NUB_PROCESS;
  if (!detaching)
    CloseChildFileDescriptors();

  m_path.clear();
  m_args.clear();
  SetState(eStateUnloaded);
  m_flags = eMachProcessFlagsNone;
  m_stop_count = 0;
  m_thread_list.Clear();
  {
    std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);
    m_exception_messages.clear();
    m_sent_interrupt_signo = 0;
    m_auto_resume_signo = 0;

  }
  m_activities.Clear();
  StopProfileThread();
}

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

void MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec,
                                          DNBProfileDataScanType scan_type) {
  m_profile_enabled = enable;
  m_profile_interval_usec = static_cast<useconds_t>(interval_usec);
  m_profile_scan_type = scan_type;

  if (m_profile_enabled && (m_profile_thread == NULL)) {
    StartProfileThread();
  } else if (!m_profile_enabled && m_profile_thread) {
    StopProfileThread();
  }
}

void MachProcess::StopProfileThread() {
  if (m_profile_thread == NULL)
    return;
  m_profile_events.SetEvents(eMachProcessProfileCancel);
  pthread_join(m_profile_thread, NULL);
  m_profile_thread = NULL;
  m_profile_events.ResetEvents(eMachProcessProfileCancel);
}

/// return 1 if bit position \a bit is set in \a value
static uint32_t bit(uint32_t value, uint32_t bit) {
  return (value >> bit) & 1u;
}

// return the bitfield "value[msbit:lsbit]".
static uint64_t bits(uint64_t value, uint32_t msbit, uint32_t lsbit) {
  assert(msbit >= lsbit);
  uint64_t shift_left = sizeof(value) * 8 - 1 - msbit;
  value <<=
      shift_left; // shift anything above the msbit off of the unsigned edge
  value >>= shift_left + lsbit; // shift it back again down to the lsbit
                                // (including undoing any shift from above)
  return value;                 // return our result
}

void MachProcess::RefineWatchpointStopInfo(
    nub_thread_t tid, struct DNBThreadStopInfo *stop_info) {
  const DNBBreakpoint *wp = m_watchpoints.FindNearestWatchpoint(
      stop_info->details.watchpoint.mach_exception_addr);
  if (wp) {
    stop_info->details.watchpoint.addr = wp->Address();
    stop_info->details.watchpoint.hw_idx = wp->GetHardwareIndex();
    DNBLogThreadedIf(LOG_WATCHPOINTS,
                     "MachProcess::RefineWatchpointStopInfo "
                     "mach exception addr 0x%llx moved in to nearest "
                     "watchpoint, 0x%llx-0x%llx",
                     stop_info->details.watchpoint.mach_exception_addr,
                     wp->Address(), wp->Address() + wp->ByteSize() - 1);
  } else {
    stop_info->details.watchpoint.addr =
        stop_info->details.watchpoint.mach_exception_addr;
  }

  stop_info->details.watchpoint.esr_fields_set = false;
  std::optional<uint64_t> esr, far;
  nub_size_t num_reg_sets = 0;
  const DNBRegisterSetInfo *reg_sets = GetRegisterSetInfo(tid, &num_reg_sets);
  for (nub_size_t set = 0; set < num_reg_sets; set++) {
    if (reg_sets[set].registers == NULL)
      continue;
    for (uint32_t reg = 0; reg < reg_sets[set].num_registers; ++reg) {
      if (strcmp(reg_sets[set].registers[reg].name, "esr") == 0) {
        std::unique_ptr<DNBRegisterValue> reg_value =
            std::make_unique<DNBRegisterValue>();
        if (GetRegisterValue(tid, set, reg, reg_value.get())) {
          esr = reg_value->value.uint64;
        }
      }
      if (strcmp(reg_sets[set].registers[reg].name, "far") == 0) {
        std::unique_ptr<DNBRegisterValue> reg_value =
            std::make_unique<DNBRegisterValue>();
        if (GetRegisterValue(tid, set, reg, reg_value.get())) {
          far = reg_value->value.uint64;
        }
      }
    }
  }

  if (esr && far) {
    if (*far != stop_info->details.watchpoint.mach_exception_addr) {
      // AFAIK the kernel is going to put the FAR value in the mach
      // exception, if they don't match, it's interesting enough to log it.
      DNBLogThreadedIf(LOG_WATCHPOINTS,
                       "MachProcess::RefineWatchpointStopInfo mach exception "
                       "addr 0x%llx but FAR register has value 0x%llx",
                       stop_info->details.watchpoint.mach_exception_addr, *far);
    }
    uint32_t exception_class = bits(*esr, 31, 26);

    // "Watchpoint exception from a lower Exception level"
    if (exception_class == 0b110100) {
      stop_info->details.watchpoint.esr_fields_set = true;
      // Documented in the ARM ARM A-Profile Dec 2022 edition
      // Section D17.2 ("General system control registers"),
      // Section D17.2.37 "ESR_EL1, Exception Syndrome Register (EL1)",
      // "Field Descriptions"
      // "ISS encoding for an exception from a Watchpoint exception"
      uint32_t iss = bits(*esr, 23, 0);
      stop_info->details.watchpoint.esr_fields.iss = iss;
      stop_info->details.watchpoint.esr_fields.wpt =
          bits(iss, 23, 18); // Watchpoint number
      stop_info->details.watchpoint.esr_fields.wptv =
          bit(iss, 17); // Watchpoint number Valid
      stop_info->details.watchpoint.esr_fields.wpf =
          bit(iss, 16); // Watchpoint might be false-positive
      stop_info->details.watchpoint.esr_fields.fnp =
          bit(iss, 15); // FAR not Precise
      stop_info->details.watchpoint.esr_fields.vncr =
          bit(iss, 13); // watchpoint from use of VNCR_EL2 reg by EL1
      stop_info->details.watchpoint.esr_fields.fnv =
          bit(iss, 10); // FAR not Valid
      stop_info->details.watchpoint.esr_fields.cm =
          bit(iss, 6); // Cache maintenance
      stop_info->details.watchpoint.esr_fields.wnr =
          bit(iss, 6); // Write not Read
      stop_info->details.watchpoint.esr_fields.dfsc =
          bits(iss, 5, 0); // Data Fault Status Code

      DNBLogThreadedIf(LOG_WATCHPOINTS,
                       "ESR watchpoint fields parsed: "
                       "iss = 0x%x, wpt = %u, wptv = %d, wpf = %d, fnp = %d, "
                       "vncr = %d, fnv = %d, cm = %d, wnr = %d, dfsc = 0x%x",
                       stop_info->details.watchpoint.esr_fields.iss,
                       stop_info->details.watchpoint.esr_fields.wpt,
                       stop_info->details.watchpoint.esr_fields.wptv,
                       stop_info->details.watchpoint.esr_fields.wpf,
                       stop_info->details.watchpoint.esr_fields.fnp,
                       stop_info->details.watchpoint.esr_fields.vncr,
                       stop_info->details.watchpoint.esr_fields.fnv,
                       stop_info->details.watchpoint.esr_fields.cm,
                       stop_info->details.watchpoint.esr_fields.wnr,
                       stop_info->details.watchpoint.esr_fields.dfsc);

      if (stop_info->details.watchpoint.esr_fields.wptv) {
        DNBLogThreadedIf(LOG_WATCHPOINTS,
                         "Watchpoint Valid field true, "
                         "finding startaddr of watchpoint %d",
                         stop_info->details.watchpoint.esr_fields.wpt);
        stop_info->details.watchpoint.hw_idx =
            stop_info->details.watchpoint.esr_fields.wpt;
        const DNBBreakpoint *wp = m_watchpoints.FindByHardwareIndex(
            stop_info->details.watchpoint.esr_fields.wpt);
        if (wp) {
          stop_info->details.watchpoint.addr = wp->Address();
        }
      }
    }
  }
}

bool MachProcess::StartProfileThread() {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__);
  // Create the thread that profiles the inferior and reports back if enabled
  return ::pthread_create(&m_profile_thread, NULL, MachProcess::ProfileThread,
                          this) == 0;
}

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

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

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

bool MachProcess::Kill(const struct timespec *timeout_abstime) {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill ()");
  nub_state_t state = DoSIGSTOP(true, false, NULL);
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() state = %s",
                   DNBStateAsString(state));
  errno = 0;
  DNBLog("Sending ptrace PT_KILL to terminate inferior process pid %d.", m_pid);
  ::ptrace(PT_KILL, m_pid, 0, 0);
  DNBError err;
  err.SetErrorToErrno();
  if (DNBLogCheckLogBit(LOG_PROCESS) || err.Fail()) {
    err.LogThreaded("MachProcess::Kill() DoSIGSTOP() ::ptrace "
            "(PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)",
            m_pid, err.Status(), err.AsString());
  }
  m_thread_actions = DNBThreadResumeActions(eStateRunning, 0);
  PrivateResume();

  // Try and reap the process without touching our m_events since
  // we want the code above this to still get the eStateExited event
  const uint32_t reap_timeout_usec =
      1000000; // Wait 1 second and try to reap the process
  const uint32_t reap_interval_usec = 10000; //
  uint32_t reap_time_elapsed;
  for (reap_time_elapsed = 0; reap_time_elapsed < reap_timeout_usec;
       reap_time_elapsed += reap_interval_usec) {
    if (GetState() == eStateExited)
      break;
    usleep(reap_interval_usec);
  }
  DNBLog("Waited %u ms for process to be reaped (state = %s)",
         reap_time_elapsed / 1000, DNBStateAsString(GetState()));
  return true;
}

bool MachProcess::Interrupt() {
  nub_state_t state = GetState();
  if (IsRunning(state)) {
    std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);
    if (m_sent_interrupt_signo == 0) {
      m_sent_interrupt_signo = SIGSTOP;
      if (Signal(m_sent_interrupt_signo)) {
        DNBLogThreadedIf(
            LOG_PROCESS,
            "MachProcess::Interrupt() - sent %i signal to interrupt process",
            m_sent_interrupt_signo);
        return true;
      } else {
        m_sent_interrupt_signo = 0;
        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - failed to "
                                      "send %i signal to interrupt process",
                         m_sent_interrupt_signo);
      }
    } else {
      // We've requested that the process stop anew; if we had recorded this
      // requested stop as being in place when we resumed (& therefore would
      // throw it away), clear that.
      m_auto_resume_signo = 0;
      DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - previously "
                                    "sent an interrupt signal %i that hasn't "
                                    "been received yet, interrupt aborted",
                       m_sent_interrupt_signo);
    }
  } else {
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - process already "
                                  "stopped, no interrupt sent");
  }
  return false;
}

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

bool MachProcess::SendEvent(const char *event, DNBError &send_err) {
  DNBLogThreadedIf(LOG_PROCESS,
                   "MachProcess::SendEvent (event = %s) to pid: %d", event,
                   m_pid);
  if (m_pid == INVALID_NUB_PROCESS)
    return false;
// FIXME: Shouldn't we use the launch flavor we were started with?
#if defined(WITH_FBS) || defined(WITH_BKS)
  return BoardServiceSendEvent(event, send_err);
#endif
  return true;
}

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

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

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

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

    PrivateResume();

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

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

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

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

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

  {
    m_thread_actions.Clear();
    m_activities.Clear();
    DNBThreadResumeAction thread_action;
    thread_action.tid = m_thread_list.ThreadIDAtIndex(thread_idx);
    thread_action.state = eStateRunning;
    thread_action.signal = -1;
    thread_action.addr = INVALID_NUB_ADDRESS;

    m_thread_actions.Append(thread_action);
    m_thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);

    std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);

    ReplyToAllExceptions();
  }

  m_task.ShutDownExceptionThread();

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

  // Resume our task
  m_task.Resume();

  // NULL our task out as we have already restored all exception ports
  m_task.Clear();
  m_platform = 0;

  // Clear out any notion of the process we once were
  const bool detaching = true;
  Clear(detaching);

  SetState(eStateDetached);

  return true;
}

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

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

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

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

  std::vector<DNBBreakpoint *> bps;

  const size_t num_bps =
      m_breakpoints.FindBreakpointsThatOverlapRange(addr, size, bps);
  if (num_bps == 0)
    return m_task.WriteMemory(addr, size, buf);

  nub_size_t bytes_written = 0;
  nub_addr_t intersect_addr;
  nub_size_t intersect_size;
  nub_size_t opcode_offset;
  const uint8_t *ubuf = (const uint8_t *)buf;

  for (size_t i = 0; i < num_bps; ++i) {
    DNBBreakpoint *bp = bps[i];

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

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

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

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

  return bytes_written;
}

void MachProcess::ReplyToAllExceptions() {
  std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);
  if (!m_exception_messages.empty()) {
    MachException::Message::iterator pos;
    MachException::Message::iterator begin = m_exception_messages.begin();
    MachException::Message::iterator end = m_exception_messages.end();
    for (pos = begin; pos != end; ++pos) {
      DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %u...",
                       (uint32_t)std::distance(begin, pos));
      int thread_reply_signal = 0;

      nub_thread_t tid =
          m_thread_list.GetThreadIDByMachPortNumber(pos->state.thread_port);
      const DNBThreadResumeAction *action = NULL;
      if (tid != INVALID_NUB_THREAD) {
        action = m_thread_actions.GetActionForThread(tid, false);
      }

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

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

    // Erase all exception message as we should have used and replied
    // to them all already.
    m_exception_messages.clear();
  }
}
void MachProcess::PrivateResume() {
  std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);

  m_auto_resume_signo = m_sent_interrupt_signo;
  if (m_auto_resume_signo)
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrivateResume() - task 0x%x "
                                  "resuming (with unhandled interrupt signal "
                                  "%i)...",
                     m_task.TaskPort(), m_auto_resume_signo);
  else
    DNBLogThreadedIf(LOG_PROCESS,
                     "MachProcess::PrivateResume() - task 0x%x resuming...",
                     m_task.TaskPort());

  ReplyToAllExceptions();
  //    bool stepOverBreakInstruction = step;

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

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

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

DNBBreakpoint *MachProcess::CreateBreakpoint(nub_addr_t addr, nub_size_t length,
                                             bool hardware) {
  DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = "
                                    "0x%8.8llx, length = %llu, hardware = %i)",
                   (uint64_t)addr, (uint64_t)length, hardware);

  DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
  if (bp)
    bp->Retain();
  else
    bp = m_breakpoints.Add(addr, length, hardware);

  if (EnableBreakpoint(addr)) {
    DNBLogThreadedIf(LOG_BREAKPOINTS,
                     "MachProcess::CreateBreakpoint ( addr = "
                     "0x%8.8llx, length = %llu) => %p",
                     (uint64_t)addr, (uint64_t)length, static_cast<void *>(bp));
    return bp;
  } else if (bp->Release() == 0) {
    m_breakpoints.Remove(addr);
  }
  // We failed to enable the breakpoint
  return NULL;
}

DNBBreakpoint *MachProcess::CreateWatchpoint(nub_addr_t addr, nub_size_t length,
                                             uint32_t watch_flags,
                                             bool hardware) {
  DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = "
                                    "0x%8.8llx, length = %llu, flags = "
                                    "0x%8.8x, hardware = %i)",
                   (uint64_t)addr, (uint64_t)length, watch_flags, hardware);

  DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
  // since the Z packets only send an address, we can only have one watchpoint
  // at
  // an address. If there is already one, we must refuse to create another
  // watchpoint
  if (wp)
    return NULL;

  wp = m_watchpoints.Add(addr, length, hardware);
  wp->SetIsWatchpoint(watch_flags);

  if (EnableWatchpoint(addr)) {
    DNBLogThreadedIf(LOG_WATCHPOINTS,
                     "MachProcess::CreateWatchpoint ( addr = "
                     "0x%8.8llx, length = %llu) => %p",
                     (uint64_t)addr, (uint64_t)length, static_cast<void *>(wp));
    return wp;
  } else {
    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = "
                                      "0x%8.8llx, length = %llu) => FAILED",
                     (uint64_t)addr, (uint64_t)length);
    m_watchpoints.Remove(addr);
  }
  // We failed to enable the watchpoint
  return NULL;
}

void MachProcess::DisableAllBreakpoints(bool remove) {
  DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::%s (remove = %d )",
                   __FUNCTION__, remove);

  m_breakpoints.DisableAllBreakpoints(this);

  if (remove)
    m_breakpoints.RemoveDisabled();
}

void MachProcess::DisableAllWatchpoints(bool remove) {
  DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s (remove = %d )",
                   __FUNCTION__, remove);

  m_watchpoints.DisableAllWatchpoints(this);

  if (remove)
    m_watchpoints.RemoveDisabled();
}

bool MachProcess::DisableBreakpoint(nub_addr_t addr, bool remove) {
  DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
  if (bp) {
    // After "exec" we might end up with a bunch of breakpoints that were
    // disabled
    // manually, just ignore them
    if (!bp->IsEnabled()) {
      // Breakpoint might have been disabled by an exec
      if (remove && bp->Release() == 0) {
        m_thread_list.NotifyBreakpointChanged(bp);
        m_breakpoints.Remove(addr);
      }
      return true;
    }

    // We have multiple references to this breakpoint, decrement the ref count
    // and if it isn't zero, then return true;
    if (remove && bp->Release() > 0)
      return true;

    DNBLogThreadedIf(
        LOG_BREAKPOINTS | LOG_VERBOSE,
        "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d )",
        (uint64_t)addr, remove);

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

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

      return false;
    }

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

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

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

bool MachProcess::DisableWatchpoint(nub_addr_t addr, bool remove) {
  DNBLogThreadedIf(LOG_WATCHPOINTS,
                   "MachProcess::%s(addr = 0x%8.8llx, remove = %d)",
                   __FUNCTION__, (uint64_t)addr, remove);
  DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
  if (wp) {
    // If we have multiple references to a watchpoint, removing the watchpoint
    // shouldn't clear it
    if (remove && wp->Release() > 0)
      return true;

    nub_addr_t addr = wp->Address();
    DNBLogThreadedIf(
        LOG_WATCHPOINTS,
        "MachProcess::DisableWatchpoint ( addr = 0x%8.8llx, remove = %d )",
        (uint64_t)addr, remove);

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

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

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

uint32_t MachProcess::GetNumSupportedHardwareWatchpoints() const {
  return m_thread_list.NumSupportedHardwareWatchpoints();
}

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

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

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

// Called by the exception thread when an exception has been received from
// our process. The exception message is completely filled and the exception
// data has already been copied.
void MachProcess::ExceptionMessageReceived(
    const MachException::Message &exceptionMessage) {
  std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);

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

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

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

task_t MachProcess::ExceptionMessageBundleComplete() {
  // We have a complete bundle of exceptions for our child process.
  std::lock_guard<std::recursive_mutex> guard(m_exception_and_signal_mutex);
  DNBLogThreadedIf(LOG_EXCEPTIONS, "%s: %llu exception messages.",
                   __PRETTY_FUNCTION__, (uint64_t)m_exception_messages.size());
  bool auto_resume = false;
  if (!m_exception_messages.empty()) {
    m_did_exec = false;
    // First check for any SIGTRAP and make sure we didn't exec
    const task_t task = m_task.TaskPort();
    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) {
          ++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 nub_addr_t aii_addr = GetDYLDAllImageInfosAddress();
            if (aii_addr != INVALID_NUB_ADDRESS) {
              const nub_addr_t info_array_count_addr = aii_addr + 4;
              uint32_t info_array_count = 0;
              if (m_task.ReadMemory(info_array_count_addr, 4,
                                    &info_array_count) == 4) {
                if (info_array_count == 0) {
                  m_did_exec = true;
                  // Force the task port to update itself in case the task port
                  // changed after exec
                  DNBError err;
                  const task_t old_task = m_task.TaskPort();
                  const task_t new_task =
                      m_task.TaskPortForProcessID(err, true);
                  if (old_task != new_task)
                    DNBLogThreadedIf(
                        LOG_PROCESS,
                        "exec: task changed from 0x%4.4x to 0x%4.4x", old_task,
                        new_task);
                }
              } else {
                DNBLog("error: failed to read all_image_infos.infoArrayCount "
                       "from 0x%8.8llx",
                       (uint64_t)info_array_count_addr);
              }
            }
            break;
          } else if (m_sent_interrupt_signo != 0 &&
                     signo == m_sent_interrupt_signo) {
            received_interrupt = true;
          }
        }
      }

      if (m_did_exec) {
        cpu_type_t process_cpu_type =
            MachProcess::GetCPUTypeForLocalProcess(m_pid);
        if (m_cpu_type != process_cpu_type) {
          DNBLog("arch changed from 0x%8.8x to 0x%8.8x", m_cpu_type,
                 process_cpu_type);
          m_cpu_type = process_cpu_type;
          DNBArchProtocol::SetArchitecture(process_cpu_type);
        }
        m_thread_list.Clear();
        m_activities.Clear();
        m_breakpoints.DisableAll();
        m_task.ClearAllocations();
      }

      if (m_sent_interrupt_signo != 0) {
        if (received_interrupt) {
          DNBLogThreadedIf(LOG_PROCESS,
                           "MachProcess::ExceptionMessageBundleComplete(): "
                           "process successfully interrupted with signal %i",
                           m_sent_interrupt_signo);

          // Mark that we received the interrupt signal
          m_sent_interrupt_signo = 0;
          // Not check if we had a case where:
          // 1 - We called MachProcess::Interrupt() but we stopped for another
          // reason
          // 2 - We called MachProcess::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;
              DNBLogThreadedIf(LOG_PROCESS, "MachProcess::"
                                            "ExceptionMessageBundleComplete(): "
                                            "auto resuming due to unhandled "
                                            "interrupt signal %i",
                               m_auto_resume_signo);
            }
            m_auto_resume_signo = 0;
          }
        } else {
          DNBLogThreadedIf(LOG_PROCESS, "MachProcess::"
                                        "ExceptionMessageBundleComplete(): "
                                        "didn't get signal %i after "
                                        "MachProcess::Interrupt()",
                           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);
    m_activities.Clear();

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

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

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

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

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

void MachProcess::SetExitInfo(const char *info) {
  if (info && info[0]) {
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s(\"%s\")", __FUNCTION__,
                     info);
    m_exit_info.assign(info);
  } else {
    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s(NULL)", __FUNCTION__);
    m_exit_info.clear();
  }
}

void MachProcess::AppendSTDOUT(char *s, size_t len) {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (<%llu> %s) ...", __FUNCTION__,
                   (uint64_t)len, s);
  std::lock_guard<std::recursive_mutex> guard(m_stdio_mutex);
  m_stdout_data.append(s, len);
  m_events.SetEvents(eEventStdioAvailable);

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

size_t MachProcess::GetAvailableSTDOUT(char *buf, size_t buf_size) {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%llu]) ...", __FUNCTION__,
                   static_cast<void *>(buf), (uint64_t)buf_size);
  std::lock_guard<std::recursive_mutex> guard(m_stdio_mutex);
  size_t bytes_available = m_stdout_data.size();
  if (bytes_available > 0) {
    if (bytes_available > buf_size) {
      memcpy(buf, m_stdout_data.data(), buf_size);
      m_stdout_data.erase(0, buf_size);
      bytes_available = buf_size;
    } else {
      memcpy(buf, m_stdout_data.data(), bytes_available);
      m_stdout_data.clear();
    }
  }
  return bytes_available;
}

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

/// From dyld SPI header dyld_process_info.h
struct dyld_process_state_info {
  uint64_t timestamp;
  uint32_t imageCount;
  uint32_t initialImageCount;
  // one of dyld_process_state_* values
  uint8_t dyldState;
};
enum {
  dyld_process_state_not_started = 0x00,
  dyld_process_state_dyld_initialized = 0x10,
  dyld_process_state_terminated_before_inits = 0x20,
  dyld_process_state_libSystem_initialized = 0x30,
  dyld_process_state_running_initializers = 0x40,
  dyld_process_state_program_running = 0x50,
  dyld_process_state_dyld_terminated = 0x60
};

JSONGenerator::ObjectSP MachProcess::GetDyldProcessState() {
  JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
  if (!m_dyld_process_info_get_state) {
    reply_sp->AddStringItem("error",
                            "_dyld_process_info_get_state unavailable");
    return reply_sp;
  }
  if (!m_dyld_process_info_create) {
    reply_sp->AddStringItem("error", "_dyld_process_info_create unavailable");
    return reply_sp;
  }

  kern_return_t kern_ret;
  dyld_process_info info =
      m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
  if (!info || kern_ret != KERN_SUCCESS) {
    reply_sp->AddStringItem(
        "error", "Unable to create dyld_process_info for inferior task");
    return reply_sp;
  }

  struct dyld_process_state_info state_info;
  m_dyld_process_info_get_state(info, &state_info);
  reply_sp->AddIntegerItem("process_state_value", state_info.dyldState);
  switch (state_info.dyldState) {
  case dyld_process_state_not_started:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_not_started");
    break;
  case dyld_process_state_dyld_initialized:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_dyld_initialized");
    break;
  case dyld_process_state_terminated_before_inits:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_terminated_before_inits");
    break;
  case dyld_process_state_libSystem_initialized:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_libSystem_initialized");
    break;
  case dyld_process_state_running_initializers:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_running_initializers");
    break;
  case dyld_process_state_program_running:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_program_running");
    break;
  case dyld_process_state_dyld_terminated:
    reply_sp->AddStringItem("process_state string",
                            "dyld_process_state_dyld_terminated");
    break;
  };

  m_dyld_process_info_release(info);

  return reply_sp;
}

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

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

#if defined(__APPLE__)
  pthread_setname_np("stdio monitoring thread");
#endif

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

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

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

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

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

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

        } while (bytes_read > 0);
      }

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

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

void MachProcess::SignalAsyncProfileData(const char *info) {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (%s) ...", __FUNCTION__, info);
  std::lock_guard<std::recursive_mutex> guard(m_profile_data_mutex);
  m_profile_data.push_back(info);
  m_events.SetEvents(eEventProfileDataAvailable);

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

size_t MachProcess::GetAsyncProfileData(char *buf, size_t buf_size) {
  DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%llu]) ...", __FUNCTION__,
                   static_cast<void *>(buf), (uint64_t)buf_size);
  std::lock_guard<std::recursive_mutex> guard(m_profile_data_mutex);
  if (m_profile_data.empty())
    return 0;

  size_t bytes_available = m_profile_data.front().size();
  if (bytes_available > 0) {
    if (bytes_available > buf_size) {
      memcpy(buf, m_profile_data.front().data(), buf_size);
      m_profile_data.front().erase(0, buf_size);
      bytes_available = buf_size;
    } else {
      memcpy(buf, m_profile_data.front().data(), bytes_available);
      m_profile_data.erase(m_profile_data.begin());
    }
  }
  return bytes_available;
}

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

#if defined(__APPLE__)
  pthread_setname_np("performance profiling thread");
#endif

  while (proc->IsProfilingEnabled()) {
    nub_state_t state = proc->GetState();
    if (state == eStateRunning) {
      std::string data =
          proc->Task().GetProfileData(proc->GetProfileScanType());
      if (!data.empty()) {
        proc->SignalAsyncProfileData(data.c_str());
      }
    } else if ((state == eStateUnloaded) || (state == eStateDetached) ||
               (state == eStateUnloaded)) {
      // Done. Get out of this thread.
      break;
    }
    timespec ts;
    {
      using namespace std::chrono;
      std::chrono::microseconds dur(proc->ProfileInterval());
      const auto dur_secs = duration_cast<seconds>(dur);
      const auto dur_usecs = dur % std::chrono::seconds(1);
      DNBTimer::OffsetTimeOfDay(&ts, dur_secs.count(), 
                                dur_usecs.count());
    }
    uint32_t bits_set = 
        proc->m_profile_events.WaitForSetEvents(eMachProcessProfileCancel, &ts);
    // If we got bits back, we were told to exit.  Do so.
    if (bits_set & eMachProcessProfileCancel)
      break;
  }
  return NULL;
}

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

    SetState(eStateAttaching);
    m_pid = pid;
    if (!m_task.StartExceptionThread(ignored_exceptions, err)) {
      const char *err_cstr = err.AsString();
      ::snprintf(err_str, err_len, "%s",
                 err_cstr ? err_cstr : "unable to start the exception thread");
      DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
      DNBLogError(
          "[LaunchAttach] END (%d) MachProcess::AttachForDebug failed to start "
          "exception thread attaching to pid %i: %s",
          getpid(), pid, err_str);
      m_pid = INVALID_NUB_PROCESS;
      return INVALID_NUB_PROCESS;
    }

    DNBLog("[LaunchAttach] (%d) About to ptrace(PT_ATTACHEXC, %d)...", getpid(),
           pid);
    errno = 0;
    int ptrace_result = ::ptrace(PT_ATTACHEXC, pid, 0, 0);
    int ptrace_errno = errno;
    DNBLog("[LaunchAttach] (%d) Completed ptrace(PT_ATTACHEXC, %d) == %d",
           getpid(), pid, ptrace_result);
    if (ptrace_result != 0) {
      err.SetError(ptrace_errno);
      DNBLogError("MachProcess::AttachForDebug failed to ptrace(PT_ATTACHEXC) "
                  "pid %i: %s",
                  pid, err.AsString());
    } else {
      err.Clear();
    }

    if (err.Success()) {
      m_flags |= eMachProcessFlagsAttached;
      DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", pid);
      return m_pid;
    } else {
      ::snprintf(err_str, err_len, "%s", err.AsString());
      DNBLogError(
          "[LaunchAttach] (%d) MachProcess::AttachForDebug error: failed to "
          "attach to pid %d",
          getpid(), pid);

      if (ProcessIsBeingDebugged(pid)) {
        nub_process_t ppid = GetParentProcessID(pid);
        if (ppid == getpid()) {
          snprintf(err_str, err_len,
                   "%s - Failed to attach to pid %d, AttachForDebug() "
                   "unable to ptrace(PT_ATTACHEXC)",
                   err.AsString(), m_pid);
        } else {
          snprintf(err_str, err_len,
                   "%s - process %d is already being debugged by pid %d",
                   err.AsString(), pid, ppid);
          DNBLogError(
              "[LaunchAttach] (%d) MachProcess::AttachForDebug pid %d is "
              "already being debugged by pid %d",
              getpid(), pid, ppid);
        }
      }
    }
  }
  return INVALID_NUB_PROCESS;
}

Genealogy::ThreadActivitySP
MachProcess::GetGenealogyInfoForThread(nub_thread_t tid, bool &timed_out) {
  return m_activities.GetGenealogyInfoForThread(m_pid, tid, m_thread_list,
                                                m_task.TaskPort(), timed_out);
}

Genealogy::ProcessExecutableInfoSP
MachProcess::GetGenealogyImageInfo(size_t idx) {
  return m_activities.GetProcessExecutableInfosAtIndex(idx);
}

bool MachProcess::GetOSVersionNumbers(uint64_t *major, uint64_t *minor,
                                      uint64_t *patch) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  NSOperatingSystemVersion vers =
      [[NSProcessInfo processInfo] operatingSystemVersion];
  if (major)
    *major = vers.majorVersion;
  if (minor)
    *minor = vers.minorVersion;
  if (patch)
    *patch = vers.patchVersion;

  [pool drain];

  return true;
}

std::string MachProcess::GetMacCatalystVersionString() {
  @autoreleasepool {
    NSDictionary *version_info =
      [NSDictionary dictionaryWithContentsOfFile:
       @"/System/Library/CoreServices/SystemVersion.plist"];
    NSString *version_value = [version_info objectForKey: @"iOSSupportVersion"];
    if (const char *version_str = [version_value UTF8String])
      return version_str;
  }
  return {};
}

nub_process_t MachProcess::GetParentProcessID(nub_process_t child_pid) {
  struct proc_bsdshortinfo proc;
  if (proc_pidinfo(child_pid, PROC_PIDT_SHORTBSDINFO, 0, &proc,
                   PROC_PIDT_SHORTBSDINFO_SIZE) == sizeof(proc)) {
    return proc.pbsi_ppid;
  }
  return INVALID_NUB_PROCESS;
}

bool MachProcess::ProcessIsBeingDebugged(nub_process_t pid) {
  struct kinfo_proc kinfo;
  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
  size_t len = sizeof(struct kinfo_proc);
  if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) == 0 &&
      (kinfo.kp_proc.p_flag & P_TRACED))
    return true;
  else
    return false;
}

#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS)
/// Get the app bundle from the given path. Returns the empty string if the
/// path doesn't appear to be an app bundle.
static std::string GetAppBundle(std::string path) {
  auto pos = path.rfind(".app");
  // Path doesn't contain `.app`.
  if (pos == std::string::npos)
    return {};
  // Path has `.app` extension.
  if (pos == path.size() - 4)
    return path.substr(0, pos + 4);

  // Look for `.app` before a path separator.
  do {
    if (path[pos + 4] == '/')
      return path.substr(0, pos + 4);
    path = path.substr(0, pos);
    pos = path.rfind(".app");
  } while (pos != std::string::npos);

  return {};
}
#endif

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

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

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

  if (!waitfor)
    return NULL;

  std::string app_bundle_path = GetAppBundle(path);
  if (app_bundle_path.empty()) {
    DNBLogThreadedIf(
        LOG_PROCESS,
        "MachProcess::PrepareForAttach(): path '%s' doesn't contain .app, "
        "we can't tell springboard to wait for launch...",
        path);
    return NULL;
  }

#if defined(WITH_FBS)
  if (launch_flavor == eLaunchFlavorDefault)
    launch_flavor = eLaunchFlavorFBS;
  if (launch_flavor != eLaunchFlavorFBS)
    return NULL;
#elif defined(WITH_BKS)
  if (launch_flavor == eLaunchFlavorDefault)
    launch_flavor = eLaunchFlavorBKS;
  if (launch_flavor != eLaunchFlavorBKS)
    return NULL;
#elif defined(WITH_SPRINGBOARD)
  if (launch_flavor == eLaunchFlavorDefault)
    launch_flavor = eLaunchFlavorSpringBoard;
  if (launch_flavor != eLaunchFlavorSpringBoard)
    return NULL;
#endif

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

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

#if defined(WITH_FBS)
  if (launch_flavor == eLaunchFlavorFBS) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *stdio_path = nil;
    NSFileManager *file_manager = [NSFileManager defaultManager];
    const char *null_path = "/dev/null";
    stdio_path =
        [file_manager stringWithFileSystemRepresentation:null_path
                                                  length:strlen(null_path)];

    NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
    NSMutableDictionary *options = [NSMutableDictionary dictionary];

    DNBLogThreadedIf(LOG_PROCESS, "Calling BKSSystemService openApplication: "
                                  "@\"%s\",options include stdio path: \"%s\", "
                                  "BKSDebugOptionKeyDebugOnNextLaunch & "
                                  "BKSDebugOptionKeyWaitForDebugger )",
                     bundleIDStr.c_str(), null_path);

    [debug_options setObject:stdio_path
                      forKey:FBSDebugOptionKeyStandardOutPath];
    [debug_options setObject:stdio_path
                      forKey:FBSDebugOptionKeyStandardErrorPath];
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:FBSDebugOptionKeyWaitForDebugger];
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:FBSDebugOptionKeyDebugOnNextLaunch];

    [options setObject:debug_options
                forKey:FBSOpenApplicationOptionKeyDebuggingOptions];

    FBSSystemService *system_service = [[FBSSystemService alloc] init];

    mach_port_t client_port = [system_service createClientPort];
    __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block FBSOpenApplicationErrorCode attach_error_code =
        FBSOpenApplicationErrorCodeNone;

    NSString *bundleIDNSStr = (NSString *)bundleIDCFStr;

    DNBLog("[LaunchAttach] START (%d) requesting FBS launch of app with bundle "
           "ID '%s'",
           getpid(), bundleIDStr.c_str());
    [system_service openApplication:bundleIDNSStr
                            options:options
                         clientPort:client_port
                         withResult:^(NSError *error) {
                           // The system service will cleanup the client port we
                           // created for us.
                           if (error)
                             attach_error_code =
                                 (FBSOpenApplicationErrorCode)[error code];

                           [system_service release];
                           dispatch_semaphore_signal(semaphore);
                         }];

    const uint32_t timeout_secs = 9;

    dispatch_time_t timeout =
        dispatch_time(DISPATCH_TIME_NOW, timeout_secs * NSEC_PER_SEC);

    long success = dispatch_semaphore_wait(semaphore, timeout) == 0;

    if (!success) {
      DNBLogError("timed out trying to launch %s.", bundleIDStr.c_str());
      attach_err.SetErrorString(
          "debugserver timed out waiting for openApplication to complete.");
      attach_err.SetError(OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
    } else if (attach_error_code != FBSOpenApplicationErrorCodeNone) {
      std::string empty_str;
      SetFBSError(attach_error_code, empty_str, attach_err);
      DNBLogError("unable to launch the application with CFBundleIdentifier "
                  "'%s' bks_error = %ld",
                  bundleIDStr.c_str(), (NSInteger)attach_error_code);
    }
    dispatch_release(semaphore);
    [pool drain];
  }
#endif
#if defined(WITH_BKS)
  if (launch_flavor == eLaunchFlavorBKS) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *stdio_path = nil;
    NSFileManager *file_manager = [NSFileManager defaultManager];
    const char *null_path = "/dev/null";
    stdio_path =
        [file_manager stringWithFileSystemRepresentation:null_path
                                                  length:strlen(null_path)];

    NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
    NSMutableDictionary *options = [NSMutableDictionary dictionary];

    DNBLogThreadedIf(LOG_PROCESS, "Calling BKSSystemService openApplication: "
                                  "@\"%s\",options include stdio path: \"%s\", "
                                  "BKSDebugOptionKeyDebugOnNextLaunch & "
                                  "BKSDebugOptionKeyWaitForDebugger )",
                     bundleIDStr.c_str(), null_path);

    [debug_options setObject:stdio_path
                      forKey:BKSDebugOptionKeyStandardOutPath];
    [debug_options setObject:stdio_path
                      forKey:BKSDebugOptionKeyStandardErrorPath];
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:BKSDebugOptionKeyWaitForDebugger];
    [debug_options setObject:[NSNumber numberWithBool:YES]
                      forKey:BKSDebugOptionKeyDebugOnNextLaunch];

    [options setObject:debug_options
                forKey:BKSOpenApplicationOptionKeyDebuggingOptions];

    BKSSystemService *system_service = [[BKSSystemService alloc] init];

    mach_port_t client_port = [system_service createClientPort];
    __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block BKSOpenApplicationErrorCode attach_error_code =
        BKSOpenApplicationErrorCodeNone;

    NSString *bundleIDNSStr = (NSString *)bundleIDCFStr;

    DNBLog("[LaunchAttach] START (%d) requesting BKS launch of app with bundle "
           "ID '%s'",
           getpid(), bundleIDStr.c_str());
    [system_service openApplication:bundleIDNSStr
                            options:options
                         clientPort:client_port
                         withResult:^(NSError *error) {
                           // The system service will cleanup the client port we
                           // created for us.
                           if (error)
                             attach_error_code =
                                 (BKSOpenApplicationErrorCode)[error code];

                           [system_service release];
                           dispatch_semaphore_signal(semaphore);
                         }];

    const uint32_t timeout_secs = 9;

    dispatch_time_t timeout =
        dispatch_time(DISPATCH_TIME_NOW, timeout_secs * NSEC_PER_SEC);

    long success = dispatch_semaphore_wait(semaphore, timeout) == 0;

    if (!success) {
      DNBLogError("timed out trying to launch %s.", bundleIDStr.c_str());
      attach_err.SetErrorString(
          "debugserver timed out waiting for openApplication to complete.");
      attach_err.SetError(OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
    } else if (attach_error_code != BKSOpenApplicationErrorCodeNone) {
      std::string empty_str;
      SetBKSError(attach_error_code, empty_str, attach_err);
      DNBLogError("unable to launch the application with CFBundleIdentifier "
                  "'%s' bks_error = %d",
                  bundleIDStr.c_str(), attach_error_code);
    }
    dispatch_release(semaphore);
    [pool drain];
  }
#endif

#if defined(WITH_SPRINGBOARD)
  if (launch_flavor == eLaunchFlavorSpringBoard) {
    SBSApplicationLaunchError sbs_error = 0;

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

    DNBLogThreadedIf(LOG_PROCESS, "SBSLaunchApplicationForDebugging ( @\"%s\" "
                                  ", NULL, NULL, NULL, @\"%s\", @\"%s\", "
                                  "SBSApplicationDebugOnNextLaunch | "
                                  "SBSApplicationLaunchWaitForDebugger )",
                     bundleIDStr.c_str(), stdout_err, stdout_err);

    DNBLog("[LaunchAttach] START (%d) requesting SpringBoard launch of app "
           "with bundle "
           "ID '%s'",
           getpid(), bundleIDStr.c_str());
    sbs_error = SBSLaunchApplicationForDebugging(
        bundleIDCFStr,
        (CFURLRef)NULL, // openURL
        NULL,           // launch_argv.get(),
        NULL,           // launch_envp.get(),  // CFDictionaryRef environment
        stdio_path.get(), stdio_path.get(),
        SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger);

    if (sbs_error != SBSApplicationLaunchErrorSuccess) {
      attach_err.SetError(sbs_error, DNBError::SpringBoard);
      return NULL;
    }
  }
#endif // WITH_SPRINGBOARD

  DNBLogThreadedIf(LOG_PROCESS, "Successfully set DebugOnNextLaunch.");
  return bundleIDCFStr;
#else // !(defined (WITH_SPRINGBOARD) || defined (WITH_BKS) || defined
      // (WITH_FBS))
  return NULL;
#endif
}

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

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

#if defined(WITH_FBS)
  if (launch_flavor == eLaunchFlavorFBS) {
    NSString *bundleIDNSStr = (NSString *)attach_token;
    FBSSystemService *systemService = [[FBSSystemService alloc] init];
    pid_t pid = [systemService pidForApplication:bundleIDNSStr];
    [systemService release];
    if (pid == 0)
      return INVALID_NUB_PROCESS;
    else
      return pid;
  }
#endif

#if defined(WITH_BKS)
  if (launch_flavor == eLaunchFlavorBKS) {
    NSString *bundleIDNSStr = (NSString *)attach_token;
    BKSSystemService *systemService = [[BKSSystemService alloc] init];
    pid_t pid = [systemService pidForApplication:bundleIDNSStr];
    [systemService release];
    if (pid == 0)
      return INVALID_NUB_PROCESS;
    else
      return pid;
  }
#endif

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

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

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

#if defined(WITH_FBS)
  if (launch_flavor == eLaunchFlavorFBS) {
    if (!success) {
      FBSCleanupAfterAttach(attach_token, err_str);
    }
    CFRelease((CFStringRef)attach_token);
  }
#endif

#if defined(WITH_BKS)

  if (launch_flavor == eLaunchFlavorBKS) {
    if (!success) {
      BKSCleanupAfterAttach(attach_token, err_str);
    }
    CFRelease((CFStringRef)attach_token);
  }
#endif

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

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

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

    CFRelease((CFStringRef)attach_token);
  }
#endif
}

pid_t MachProcess::LaunchForDebug(
    const char *path, char const *argv[], char const *envp[],
    const char *working_directory, // NULL => 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, 
    const RNBContext::IgnoredExceptions &ignored_exceptions, 
    DNBError &launch_err) {
  // Clear out and clean up from any current state
  Clear();

  DNBLogThreadedIf(LOG_PROCESS,
                   "%s( path = '%s', argv = %p, envp = %p, "
                   "launch_flavor = %u, disable_aslr = %d )",
                   __FUNCTION__, path, static_cast<const void *>(argv),
                   static_cast<const void *>(envp), launch_flavor,
                   disable_aslr);

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

  switch (launch_flavor) {
  case eLaunchFlavorForkExec:
    m_pid = MachProcess::ForkChildForPTraceDebugging(path, argv, envp, this,
                                                     launch_err);
    break;
#ifdef WITH_FBS
  case eLaunchFlavorFBS: {
    std::string app_bundle_path = GetAppBundle(path);
    if (!app_bundle_path.empty()) {
      m_flags |= (eMachProcessFlagsUsingFBS | eMachProcessFlagsBoardCalculated);
      if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
                                     no_stdio, disable_aslr, event_data,
                                     ignored_exceptions, launch_err) != 0)
        return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                      // non-zero m_pid.
    }
    DNBLog("Failed to launch '%s' with FBS", app_bundle_path.c_str());
  } break;
#endif
#ifdef WITH_BKS
  case eLaunchFlavorBKS: {
    std::string app_bundle_path = GetAppBundle(path);
    if (!app_bundle_path.empty()) {
      m_flags |= (eMachProcessFlagsUsingBKS | eMachProcessFlagsBoardCalculated);
      if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
                                     no_stdio, disable_aslr, event_data,
                                     ignored_exceptions, launch_err) != 0)
        return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                      // non-zero m_pid.
    }
    DNBLog("Failed to launch '%s' with BKS", app_bundle_path.c_str());
  } break;
#endif
#ifdef WITH_SPRINGBOARD
  case eLaunchFlavorSpringBoard: {
    std::string app_bundle_path = GetAppBundle(path);
    if (!app_bundle_path.empty()) {
      if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio,
                           disable_aslr, ignored_exceptions, launch_err) != 0)
        return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                      // non-zero m_pid.
    }
    DNBLog("Failed to launch '%s' with SpringBoard", app_bundle_path.c_str());
  } break;

#endif

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

  default:
    DNBLog("Failed to launch: invalid launch flavor: %d", launch_flavor);
    launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
    return INVALID_NUB_PROCESS;
  }

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

    m_task.StartExceptionThread(ignored_exceptions, launch_err);
    if (launch_err.Fail()) {
      if (launch_err.AsString() == NULL)
        launch_err.SetErrorString("unable to start the exception thread");
      DNBLog("Could not get inferior's Mach exception port, sending ptrace "
             "PT_KILL and exiting.");
      ::ptrace(PT_KILL, m_pid, 0, 0);
      m_pid = INVALID_NUB_PROCESS;
      return INVALID_NUB_PROCESS;
    }

    StartSTDIOThread();

    if (launch_flavor == eLaunchFlavorPosixSpawn) {

      SetState(eStateAttaching);
      errno = 0;
      DNBLog("[LaunchAttach] (%d) About to ptrace(PT_ATTACHEXC, %d)...",
             getpid(), m_pid);
      int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
      int ptrace_errno = errno;
      DNBLog("[LaunchAttach] (%d) Completed ptrace(PT_ATTACHEXC, %d) == %d",
             getpid(), m_pid, err);
      if (err == 0) {
        m_flags |= eMachProcessFlagsAttached;
        DNBLogThreadedIf(LOG_PROCESS, "successfully spawned pid %d", m_pid);
        launch_err.Clear();
      } else {
        SetState(eStateExited);
        DNBError ptrace_err(ptrace_errno, DNBError::POSIX);
        DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to spawned pid "
                                      "%d (err = %i, errno = %i (%s))",
                         m_pid, err, ptrace_err.Status(),
                         ptrace_err.AsString());
        char err_msg[PATH_MAX];

        snprintf(err_msg, sizeof(err_msg),
                 "Failed to attach to pid %d, LaunchForDebug() unable to "
                 "ptrace(PT_ATTACHEXC)",
                 m_pid);
        launch_err.SetErrorString(err_msg);
      }
    } else {
      launch_err.Clear();
    }
  }
  return m_pid;
}

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

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

  flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF |
          POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETPGROUP;
  if (disable_aslr)
    flags |= _POSIX_SPAWN_DISABLE_ASLR;

  sigset_t no_signals;
  sigset_t all_signals;
  sigemptyset(&no_signals);
  sigfillset(&all_signals);
  ::posix_spawnattr_setsigmask(&attr, &no_signals);
  ::posix_spawnattr_setsigdefault(&attr, &all_signals);

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

// Don't do this on SnowLeopard, _sometimes_ the TASK_BASIC_INFO will fail
// and we will fail to continue with our process...

// On SnowLeopard we should set "DYLD_NO_PIE" in the inferior environment....

  if (cpu_type != 0) {
    size_t ocount = 0;
    bool slice_preference_set = false;

    if (cpu_subtype != 0) {
      typedef int (*posix_spawnattr_setarchpref_np_t)(
          posix_spawnattr_t *, size_t, cpu_type_t *, cpu_subtype_t *, size_t *);
      posix_spawnattr_setarchpref_np_t posix_spawnattr_setarchpref_np_fn =
          (posix_spawnattr_setarchpref_np_t)dlsym(
              RTLD_DEFAULT, "posix_spawnattr_setarchpref_np");
      if (posix_spawnattr_setarchpref_np_fn) {
        err.SetError((*posix_spawnattr_setarchpref_np_fn)(
            &attr, 1, &cpu_type, &cpu_subtype, &ocount));
        slice_preference_set = err.Success();
        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
          err.LogThreaded(
              "::posix_spawnattr_setarchpref_np ( &attr, 1, cpu_type = "
              "0x%8.8x, cpu_subtype = 0x%8.8x, count => %llu )",
              cpu_type, cpu_subtype, (uint64_t)ocount);
        if (err.Fail() != 0 || ocount != 1)
          return INVALID_NUB_PROCESS;
      }
    }

    if (!slice_preference_set) {
      err.SetError(
          ::posix_spawnattr_setbinpref_np(&attr, 1, &cpu_type, &ocount),
          DNBError::POSIX);
      if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
        err.LogThreaded(
            "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = "
            "0x%8.8x, count => %llu )",
            cpu_type, (uint64_t)ocount);

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

  PseudoTerminal pty;

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

    // if no_stdio or std paths not supplied, then route to "/dev/null".
    if (no_stdio || stdin_path == NULL || stdin_path[0] == '\0')
      stdin_path = "/dev/null";
    if (no_stdio || stdout_path == NULL || stdout_path[0] == '\0')
      stdout_path = "/dev/null";
    if (no_stdio || stderr_path == NULL || stderr_path[0] == '\0')
      stderr_path = "/dev/null";

    err.SetError(::posix_spawn_file_actions_addopen(&file_actions, STDIN_FILENO,
                                                    stdin_path,
                                                    O_RDONLY | O_NOCTTY, 0),
                 DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
      err.LogThreaded("::posix_spawn_file_actions_addopen (&file_actions, "
                      "filedes=STDIN_FILENO, path='%s')",
                      stdin_path);

    err.SetError(::posix_spawn_file_actions_addopen(
                     &file_actions, STDOUT_FILENO, stdout_path,
                     O_WRONLY | O_NOCTTY | O_CREAT, 0640),
                 DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
      err.LogThreaded("::posix_spawn_file_actions_addopen (&file_actions, "
                      "filedes=STDOUT_FILENO, path='%s')",
                      stdout_path);

    err.SetError(::posix_spawn_file_actions_addopen(
                     &file_actions, STDERR_FILENO, stderr_path,
                     O_WRONLY | O_NOCTTY | O_CREAT, 0640),
                 DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
      err.LogThreaded("::posix_spawn_file_actions_addopen (&file_actions, "
                      "filedes=STDERR_FILENO, path='%s')",
                      stderr_path);

    // TODO: Verify if we can set the working directory back immediately
    // after the posix_spawnp call without creating a race condition???
    if (working_directory)
      ::chdir(working_directory);

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

    err.SetError(::posix_spawnp(&pid, path, NULL, &attr,
                                const_cast<char *const *>(argv),
                                const_cast<char *const *>(envp)),
                 DNBError::POSIX);
    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
      err.LogThreaded("::posix_spawnp ( pid => %i, path = '%s', file_actions = "
                      "%p, attr = %p, argv = %p, envp = %p )",
                      pid, path, NULL, &attr, argv, envp);
  }

  // We have seen some cases where posix_spawnp was returning a valid
  // looking pid even when an error was returned, so clear it out
  if (err.Fail())
    pid = INVALID_NUB_PROCESS;

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

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

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

  return pid;
}

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

  mib[len] = pid;
  len++;

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

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

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

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

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

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

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

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

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

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

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

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

  return bundleIDCFStr;
}
#endif // #if defined (WITH_SPRINGBOARD) || defined (WITH_BKS) || defined
       // (WITH_FBS)
#ifdef WITH_SPRINGBOARD

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

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

  // Fork a child process for debugging
  SetState(eStateLaunching);
  m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio,
                                                     this, launch_err);
  if (m_pid != 0) {
    m_path = path;
    size_t i;
    char const *arg;
    for (i = 0; (arg = argv[i]) != NULL; i++)
      m_args.push_back(arg);
    m_task.StartExceptionThread(ignored_exceptions, launch_err);

    if (launch_err.Fail()) {
      if (launch_err.AsString() == NULL)
        launch_err.SetErrorString("unable to start the exception thread");
      DNBLog("Could not get inferior's Mach exception port, sending ptrace "
             "PT_KILL and exiting.");
      ::ptrace(PT_KILL, m_pid, 0, 0);
      m_pid = INVALID_NUB_PROCESS;
      return INVALID_NUB_PROCESS;
    }

    StartSTDIOThread();
    SetState(eStateAttaching);
    DNBLog("[LaunchAttach] (%d) About to ptrace(PT_ATTACHEXC, %d)...", getpid(),
           m_pid);
    int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
    DNBLog("[LaunchAttach] (%d) Completed ptrace(PT_ATTACHEXC, %d) == %d",
           getpid(), m_pid, err);
    if (err == 0) {
      m_flags |= eMachProcessFlagsAttached;
      DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", m_pid);
    } else {
      launch_err.SetErrorString(
          "Failed to attach to pid %d, SBLaunchForDebug() unable to "
          "ptrace(PT_ATTACHEXC)",
          m_pid);
      SetState(eStateExited);
      DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", m_pid);
    }
  }
  return m_pid;
}

#include <servers/bootstrap.h>

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

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

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

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

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

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

  CFReleaser<CFMutableDictionaryRef> launch_envp;

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

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

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

      name_len = value - envp[i];

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

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

  CFString stdio_path;

  PseudoTerminal pty;
  if (!no_stdio) {
    PseudoTerminal::Status pty_err =
        pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY);
    if (pty_err == PseudoTerminal::success) {
      const char *secondary_name = pty.SecondaryName();
      DNBLogThreadedIf(LOG_PROCESS,
                       "%s() successfully opened primary pty, secondary is %s",
                       __FUNCTION__, secondary_name);
      if (secondary_name && secondary_name[0]) {
        ::chmod(secondary_name, S_IRWXU | S_IRWXG | S_IRWXO);
        stdio_path.SetFileSystemRepresentation(secondary_name);
      }
    }
  }

  if (stdio_path.get() == NULL) {
    stdio_path.SetFileSystemRepresentation("/dev/null");
  }

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

  // This is just for logging:
  std::string bundleID;
  CFString::UTF8(bundleIDCFStr, bundleID);

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

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

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

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

    useconds_t pid_poll_total = 0;

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

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

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

#endif // #ifdef WITH_SPRINGBOARD

#if defined(WITH_BKS) || defined(WITH_FBS)
pid_t MachProcess::BoardServiceLaunchForDebug(
    const char *path, char const *argv[], char const *envp[], bool no_stdio,
    bool disable_aslr, const char *event_data, 
    const RNBContext::IgnoredExceptions &ignored_exceptions,
    DNBError &launch_err) {
  DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);

  // Fork a child process for debugging
  SetState(eStateLaunching);
  m_pid = BoardServiceForkChildForPTraceDebugging(
      path, argv, envp, no_stdio, disable_aslr, event_data, launch_err);
  if (m_pid != 0) {
    m_path = path;
    size_t i;
    char const *arg;
    for (i = 0; (arg = argv[i]) != NULL; i++)
      m_args.push_back(arg);
    m_task.StartExceptionThread(ignored_exceptions, launch_err);

    if (launch_err.Fail()) {
      if (launch_err.AsString() == NULL)
        launch_err.SetErrorString("unable to start the exception thread");
      DNBLog("[LaunchAttach] END (%d) Could not get inferior's Mach exception "
             "port, "
             "sending ptrace "
             "PT_KILL to pid %i and exiting.",
             getpid(), m_pid);
      ::ptrace(PT_KILL, m_pid, 0, 0);
      m_pid = INVALID_NUB_PROCESS;
      return INVALID_NUB_PROCESS;
    }

    StartSTDIOThread();
    SetState(eStateAttaching);
    DNBLog("[LaunchAttach] (%d) About to ptrace(PT_ATTACHEXC, %d)...", getpid(),
           m_pid);
    int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
    DNBLog("[LaunchAttach] (%d) Completed ptrace(PT_ATTACHEXC, %d) == %d",
           getpid(), m_pid, err);
    if (err == 0) {
      m_flags |= eMachProcessFlagsAttached;
      DNBLog("[LaunchAttach] successfully attached to pid %d", m_pid);
    } else {
      std::string errmsg = "Failed to attach to pid ";
      errmsg += std::to_string(m_pid);
      errmsg += ", BoardServiceLaunchForDebug() unable to ptrace(PT_ATTACHEXC)";
      launch_err.SetErrorString(errmsg.c_str());
      SetState(eStateExited);
      DNBLog("[LaunchAttach] END (%d) error: failed to attach to pid %d",
             getpid(), m_pid);
    }
  }
  return m_pid;
}

pid_t MachProcess::BoardServiceForkChildForPTraceDebugging(
    const char *app_bundle_path, char const *argv[], char const *envp[],
    bool no_stdio, bool disable_aslr, const char *event_data,
    DNBError &launch_err) {
  if (argv[0] == NULL)
    return INVALID_NUB_PROCESS;

  DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__,
                   app_bundle_path, this);

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

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

  // Enumerate the arguments
  size_t first_launch_arg_idx = 1;

  NSMutableArray *launch_argv = nil;

  if (argv[first_launch_arg_idx]) {
    size_t launch_argc = argc > 0 ? argc - 1 : 0;
    launch_argv = [NSMutableArray arrayWithCapacity:launch_argc];
    size_t i;
    char const *arg;
    NSString *launch_arg;
    for (i = first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL);
         i++) {
      launch_arg = [NSString stringWithUTF8String:arg];
      // FIXME: Should we silently eat an argument that we can't convert into a
      // UTF8 string?
      if (launch_arg != nil)
        [launch_argv addObject:launch_arg];
      else
        break;
    }
  }

  NSMutableDictionary *launch_envp = nil;
  if (envp[0]) {
    launch_envp = [[NSMutableDictionary alloc] init];
    const char *value;
    int name_len;
    NSString *name_string, *value_string;

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

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

      name_len = value - envp[i];

      // Now move value over the "="
      value++;
      name_string = [[NSString alloc] initWithBytes:envp[i]
                                             length:name_len
                                           encoding:NSUTF8StringEncoding];
      value_string = [NSString stringWithUTF8String:value];
      [launch_envp setObject:value_string forKey:name_string];
    }
  }

  NSString *stdio_path = nil;
  NSFileManager *file_manager = [NSFileManager defaultManager];

  PseudoTerminal pty;
  if (!no_stdio) {
    PseudoTerminal::Status pty_err =
        pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY);
    if (pty_err == PseudoTerminal::success) {
      const char *secondary_name = pty.SecondaryName();
      DNBLogThreadedIf(LOG_PROCESS,
                       "%s() successfully opened primary pty, secondary is %s",
                       __FUNCTION__, secondary_name);
      if (secondary_name && secondary_name[0]) {
        ::chmod(secondary_name, S_IRWXU | S_IRWXG | S_IRWXO);
        stdio_path = [file_manager
            stringWithFileSystemRepresentation:secondary_name
                                        length:strlen(secondary_name)];
      }
    }
  }

  if (stdio_path == nil) {
    const char *null_path = "/dev/null";
    stdio_path =
        [file_manager stringWithFileSystemRepresentation:null_path
                                                  length:strlen(null_path)];
  }

  CFStringRef bundleIDCFStr = CopyBundleIDForPath(app_bundle_path, launch_err);
  if (bundleIDCFStr == NULL) {
    [pool drain];
    return INVALID_NUB_PROCESS;
  }

  // Instead of rewriting CopyBundleIDForPath for NSStrings, we'll just use
  // toll-free bridging here:
  NSString *bundleIDNSStr = (NSString *)bundleIDCFStr;

  // Okay, now let's assemble all these goodies into the BackBoardServices
  // options mega-dictionary:

  NSMutableDictionary *options = nullptr;
  pid_t return_pid = INVALID_NUB_PROCESS;
  bool success = false;

#ifdef WITH_BKS
  if (ProcessUsingBackBoard()) {
    options =
        BKSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
                                   stdio_path, disable_aslr, event_data);
    success = BKSCallOpenApplicationFunction(bundleIDNSStr, options, launch_err,
                                             &return_pid);
  }
#endif
#ifdef WITH_FBS
  if (ProcessUsingFrontBoard()) {
    options =
        FBSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
                                   stdio_path, disable_aslr, event_data);
    success = FBSCallOpenApplicationFunction(bundleIDNSStr, options, launch_err,
                                             &return_pid);
  }
#endif

  if (success) {
    int primary_fd = pty.ReleasePrimaryFD();
    SetChildFileDescriptors(primary_fd, primary_fd, primary_fd);
    CFString::UTF8(bundleIDCFStr, m_bundle_id);
  }

  [pool drain];

  return return_pid;
}

bool MachProcess::BoardServiceSendEvent(const char *event_data,
                                        DNBError &send_err) {
  bool return_value = true;

  if (event_data == NULL || *event_data == '\0') {
    DNBLogError("SendEvent called with NULL event data.");
    send_err.SetErrorString("SendEvent called with empty event data");
    return false;
  }

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  if (strcmp(event_data, "BackgroundApplication") == 0) {
// This is an event I cooked up.  What you actually do is foreground the system
// app, so:
#ifdef WITH_BKS
    if (ProcessUsingBackBoard()) {
      return_value = BKSCallOpenApplicationFunction(nil, nil, send_err, NULL);
    }
#endif
#ifdef WITH_FBS
    if (ProcessUsingFrontBoard()) {
      return_value = FBSCallOpenApplicationFunction(nil, nil, send_err, NULL);
    }
#endif
    if (!return_value) {
      DNBLogError("Failed to background application, error: %s.",
                  send_err.AsString());
    }
  } else {
    if (m_bundle_id.empty()) {
      // See if we can figure out the bundle ID for this PID:

      DNBLogError(
          "Tried to send event \"%s\" to a process that has no bundle ID.",
          event_data);
      return false;
    }

    NSString *bundleIDNSStr =
        [NSString stringWithUTF8String:m_bundle_id.c_str()];

    NSMutableDictionary *options = [NSMutableDictionary dictionary];

#ifdef WITH_BKS
    if (ProcessUsingBackBoard()) {
      if (!BKSAddEventDataToOptions(options, event_data, send_err)) {
        [pool drain];
        return false;
      }
      return_value = BKSCallOpenApplicationFunction(bundleIDNSStr, options,
                                                    send_err, NULL);
      DNBLogThreadedIf(LOG_PROCESS,
                       "Called BKSCallOpenApplicationFunction to send event.");
    }
#endif
#ifdef WITH_FBS
    if (ProcessUsingFrontBoard()) {
      if (!FBSAddEventDataToOptions(options, event_data, send_err)) {
        [pool drain];
        return false;
      }
      return_value = FBSCallOpenApplicationFunction(bundleIDNSStr, options,
                                                    send_err, NULL);
      DNBLogThreadedIf(LOG_PROCESS,
                       "Called FBSCallOpenApplicationFunction to send event.");
    }
#endif

    if (!return_value) {
      DNBLogError("Failed to send event: %s, error: %s.", event_data,
                  send_err.AsString());
    }
  }

  [pool drain];
  return return_value;
}
#endif // defined(WITH_BKS) || defined (WITH_FBS)

#ifdef WITH_BKS
void MachProcess::BKSCleanupAfterAttach(const void *attach_token,
                                        DNBError &err_str) {
  bool success;

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  // Instead of rewriting CopyBundleIDForPath for NSStrings, we'll just use
  // toll-free bridging here:
  NSString *bundleIDNSStr = (NSString *)attach_token;

  // Okay, now let's assemble all these goodies into the BackBoardServices
  // options mega-dictionary:

  // First we have the debug sub-dictionary:
  NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
  [debug_options setObject:[NSNumber numberWithBool:YES]
                    forKey:BKSDebugOptionKeyCancelDebugOnNextLaunch];

  // That will go in the overall dictionary:

  NSMutableDictionary *options = [NSMutableDictionary dictionary];
  [options setObject:debug_options
              forKey:BKSOpenApplicationOptionKeyDebuggingOptions];

  success =
      BKSCallOpenApplicationFunction(bundleIDNSStr, options, err_str, NULL);

  if (!success) {
    DNBLogError("error trying to cancel debug on next launch for %s: %s",
                [bundleIDNSStr UTF8String], err_str.AsString());
  }

  [pool drain];
}
#endif // WITH_BKS

#ifdef WITH_FBS
void MachProcess::FBSCleanupAfterAttach(const void *attach_token,
                                        DNBError &err_str) {
  bool success;

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  // Instead of rewriting CopyBundleIDForPath for NSStrings, we'll just use
  // toll-free bridging here:
  NSString *bundleIDNSStr = (NSString *)attach_token;

  // Okay, now let's assemble all these goodies into the BackBoardServices
  // options mega-dictionary:

  // First we have the debug sub-dictionary:
  NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
  [debug_options setObject:[NSNumber numberWithBool:YES]
                    forKey:FBSDebugOptionKeyCancelDebugOnNextLaunch];

  // That will go in the overall dictionary:

  NSMutableDictionary *options = [NSMutableDictionary dictionary];
  [options setObject:debug_options
              forKey:FBSOpenApplicationOptionKeyDebuggingOptions];

  success =
      FBSCallOpenApplicationFunction(bundleIDNSStr, options, err_str, NULL);

  if (!success) {
    DNBLogError("error trying to cancel debug on next launch for %s: %s",
                [bundleIDNSStr UTF8String], err_str.AsString());
  }

  [pool drain];
}
#endif // WITH_FBS


void MachProcess::CalculateBoardStatus()
{
  if (m_flags & eMachProcessFlagsBoardCalculated)
    return;
  if (m_pid == 0)
    return;

#if defined (WITH_FBS) || defined (WITH_BKS)
    bool found_app_flavor = false;
#endif

#if defined(WITH_FBS)
    if (!found_app_flavor && IsFBSProcess(m_pid)) {
      found_app_flavor = true;
      m_flags |= eMachProcessFlagsUsingFBS;
    }
#endif
#if defined(WITH_BKS)
    if (!found_app_flavor && IsBKSProcess(m_pid)) {
      found_app_flavor = true;
      m_flags |= eMachProcessFlagsUsingBKS;
    }
#endif

    m_flags |= eMachProcessFlagsBoardCalculated;
}

bool MachProcess::ProcessUsingBackBoard() {
  CalculateBoardStatus();
  return (m_flags & eMachProcessFlagsUsingBKS) != 0;
}

bool MachProcess::ProcessUsingFrontBoard() {
  CalculateBoardStatus();
  return (m_flags & eMachProcessFlagsUsingFBS) != 0;
}

int MachProcess::GetInferiorAddrSize(pid_t pid) {
  int pointer_size = 8;
  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
  struct kinfo_proc processInfo;
  size_t bufsize = sizeof(processInfo);
  if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize,
             NULL, 0) == 0 &&
      bufsize > 0) {
    if ((processInfo.kp_proc.p_flag & P_LP64) == 0)
      pointer_size = 4;
  }
  return pointer_size;
}
