//===-- debugserver.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
//
//===----------------------------------------------------------------------===//

#include <arpa/inet.h>
#include <asl.h>
#include <crt_externs.h>
#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/un.h>

#include <memory>
#include <vector>

#if defined(__APPLE__)
#include <sched.h>
extern "C" int proc_set_wakemon_params(pid_t, int,
                                       int); // <libproc_internal.h> SPI
#endif

#include "CFString.h"
#include "DNB.h"
#include "DNBLog.h"
#include "DNBTimer.h"
#include "OsLogger.h"
#include "PseudoTerminal.h"
#include "RNBContext.h"
#include "RNBRemote.h"
#include "RNBServices.h"
#include "RNBSocket.h"
#include "SysSignal.h"

// Global PID in case we get a signal and need to stop the process...
nub_process_t g_pid = INVALID_NUB_PROCESS;

// Run loop modes which determine which run loop function will be called
enum RNBRunLoopMode {
  eRNBRunLoopModeInvalid = 0,
  eRNBRunLoopModeGetStartModeFromRemoteProtocol,
  eRNBRunLoopModeInferiorAttaching,
  eRNBRunLoopModeInferiorLaunching,
  eRNBRunLoopModeInferiorExecuting,
  eRNBRunLoopModePlatformMode,
  eRNBRunLoopModeExit
};

// Global Variables
RNBRemoteSP g_remoteSP;
static int g_lockdown_opt = 0;
static int g_applist_opt = 0;
static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault;
int g_disable_aslr = 0;

int g_isatty = 0;
bool g_detach_on_error = true;

#define RNBLogSTDOUT(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stdout, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)
#define RNBLogSTDERR(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stderr, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)

// Get our program path and arguments from the remote connection.
// We will need to start up the remote connection without a PID, get the
// arguments, wait for the new process to finish launching and hit its
// entry point,  and then return the run loop mode that should come next.
RNBRunLoopMode RNBRunLoopGetStartModeFromRemote(RNBRemote *remote) {
  std::string packet;

  if (remote) {
    RNBContext &ctx = remote->Context();
    uint32_t event_mask = RNBContext::event_read_packet_available |
                          RNBContext::event_read_thread_exiting;

    // Spin waiting to get the A packet.
    while (true) {
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",
                       __FUNCTION__, event_mask);
      nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x",
                       __FUNCTION__, event_mask, set_events);

      if (set_events & RNBContext::event_read_thread_exiting) {
        RNBLogSTDERR("error: packet read thread exited.\n");
        return eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_packet_available) {
        rnb_err_t err = rnb_err;
        RNBRemote::PacketEnum type;

        err = remote->HandleReceivedPacket(&type);

        // check if we tried to attach to a process
        if (type == RNBRemote::vattach || type == RNBRemote::vattachwait ||
            type == RNBRemote::vattachorwait) {
          if (err == rnb_success) {
            RNBLogSTDOUT("Attach succeeded, ready to debug.\n");
            return eRNBRunLoopModeInferiorExecuting;
          } else {
            RNBLogSTDERR("error: attach failed.\n");
            return eRNBRunLoopModeExit;
          }
        }

        if (err == rnb_success) {
          // If we got our arguments we are ready to launch using the arguments
          // and any environment variables we received.
          if (type == RNBRemote::set_argv) {
            return eRNBRunLoopModeInferiorLaunching;
          }
        } else if (err == rnb_not_connected) {
          RNBLogSTDERR("error: connection lost.\n");
          return eRNBRunLoopModeExit;
        } else {
          // a catch all for any other gdb remote packets that failed
          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
                           __FUNCTION__);
          continue;
        }

        DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
      } else {
        DNBLogThreadedIf(LOG_RNB_MINIMAL,
                         "%s Connection closed before getting \"A\" packet.",
                         __FUNCTION__);
        return eRNBRunLoopModeExit;
      }
    }
  }
  return eRNBRunLoopModeExit;
}

// This run loop mode will wait for the process to launch and hit its
// entry point. It will currently ignore all events except for the
// process state changed event, where it watches for the process stopped
// or crash process state.
RNBRunLoopMode RNBRunLoopLaunchInferior(RNBRemote *remote,
                                        const char *stdin_path,
                                        const char *stdout_path,
                                        const char *stderr_path,
                                        bool no_stdio) {
  RNBContext &ctx = remote->Context();

  // The Process stuff takes a c array, the RNBContext has a vector...
  // So make up a c array.

  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Launching '%s'...", __FUNCTION__,
                   ctx.ArgumentAtIndex(0));

  size_t inferior_argc = ctx.ArgumentCount();
  // Initialize inferior_argv with inferior_argc + 1 NULLs
  std::vector<const char *> inferior_argv(inferior_argc + 1, NULL);

  size_t i;
  for (i = 0; i < inferior_argc; i++)
    inferior_argv[i] = ctx.ArgumentAtIndex(i);

  // Pass the environment array the same way:

  size_t inferior_envc = ctx.EnvironmentCount();
  // Initialize inferior_argv with inferior_argc + 1 NULLs
  std::vector<const char *> inferior_envp(inferior_envc + 1, NULL);

  for (i = 0; i < inferior_envc; i++)
    inferior_envp[i] = ctx.EnvironmentAtIndex(i);

  // Our launch type hasn't been set to anything concrete, so we need to
  // figure our how we are going to launch automatically.

  nub_launch_flavor_t launch_flavor = g_launch_flavor;
  if (launch_flavor == eLaunchFlavorDefault) {
    // Our default launch method is posix spawn
    launch_flavor = eLaunchFlavorPosixSpawn;

#if defined WITH_FBS
    // Check if we have an app bundle, if so launch using BackBoard Services.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorFBS;
    }
#elif defined WITH_BKS
    // Check if we have an app bundle, if so launch using BackBoard Services.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorBKS;
    }
#elif defined WITH_SPRINGBOARD
    // Check if we have an app bundle, if so launch using SpringBoard.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorSpringBoard;
    }
#endif
  }

  ctx.SetLaunchFlavor(launch_flavor);
  char resolved_path[PATH_MAX];

  // If we fail to resolve the path to our executable, then just use what we
  // were given and hope for the best
  if (!DNBResolveExecutablePath(inferior_argv[0], resolved_path,
                                sizeof(resolved_path)))
    ::strlcpy(resolved_path, inferior_argv[0], sizeof(resolved_path));

  char launch_err_str[PATH_MAX];
  launch_err_str[0] = '\0';
  const char *cwd =
      (ctx.GetWorkingDirPath() != NULL ? ctx.GetWorkingDirPath()
                                       : ctx.GetWorkingDirectory());
  const char *process_event = ctx.GetProcessEvent();
  nub_process_t pid = DNBProcessLaunch(
      resolved_path, &inferior_argv[0], &inferior_envp[0], cwd, stdin_path,
      stdout_path, stderr_path, no_stdio, launch_flavor, g_disable_aslr,
      process_event, launch_err_str, sizeof(launch_err_str));

  g_pid = pid;

  if (pid == INVALID_NUB_PROCESS && strlen(launch_err_str) > 0) {
    DNBLogThreaded("%s DNBProcessLaunch() returned error: '%s'", __FUNCTION__,
                   launch_err_str);
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    ctx.LaunchStatus().SetErrorString(launch_err_str);
  } else if (pid == INVALID_NUB_PROCESS) {
    DNBLogThreaded(
        "%s DNBProcessLaunch() failed to launch process, unknown failure",
        __FUNCTION__);
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    ctx.LaunchStatus().SetErrorString("<unknown failure>");
  } else {
    ctx.LaunchStatus().Clear();
  }

  if (remote->Comm().IsConnected()) {
    // It we are connected already, the next thing gdb will do is ask
    // whether the launch succeeded, and if not, whether there is an
    // error code.  So we need to fetch one packet from gdb before we wait
    // on the stop from the target.

    uint32_t event_mask = RNBContext::event_read_packet_available;
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);

    if (set_events & RNBContext::event_read_packet_available) {
      rnb_err_t err = rnb_err;
      RNBRemote::PacketEnum type;

      err = remote->HandleReceivedPacket(&type);

      if (err != rnb_success) {
        DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
                         __FUNCTION__);
        return eRNBRunLoopModeExit;
      }
      if (type != RNBRemote::query_launch_success) {
        DNBLogThreadedIf(LOG_RNB_MINIMAL,
                         "%s Didn't get the expected qLaunchSuccess packet.",
                         __FUNCTION__);
      }
    }
  }

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

    if (set_events == 0) {
      pid = INVALID_NUB_PROCESS;
      g_pid = pid;
    } else {
      if (set_events & (eEventProcessRunningStateChanged |
                        eEventProcessStoppedStateChanged)) {
        nub_state_t pid_state = DNBProcessGetState(pid);
        DNBLogThreadedIf(
            LOG_RNB_EVENTS,
            "%s process %4.4x state changed (eEventProcessStateChanged): %s",
            __FUNCTION__, pid, DNBStateAsString(pid_state));

        switch (pid_state) {
        case eStateInvalid:
        case eStateUnloaded:
        case eStateAttaching:
        case eStateLaunching:
        case eStateSuspended:
          break; // Ignore

        case eStateRunning:
        case eStateStepping:
          // Still waiting to stop at entry point...
          break;

        case eStateStopped:
        case eStateCrashed:
          ctx.SetProcessID(pid);
          return eRNBRunLoopModeInferiorExecuting;

        case eStateDetached:
        case eStateExited:
          pid = INVALID_NUB_PROCESS;
          g_pid = pid;
          return eRNBRunLoopModeExit;
        }
      }

      DNBProcessResetEvents(pid, set_events);
    }
  }

  return eRNBRunLoopModeExit;
}

// This run loop mode will wait for the process to launch and hit its
// entry point. It will currently ignore all events except for the
// process state changed event, where it watches for the process stopped
// or crash process state.
RNBRunLoopMode RNBRunLoopLaunchAttaching(RNBRemote *remote,
                                         nub_process_t attach_pid,
                                         nub_process_t &pid) {
  RNBContext &ctx = remote->Context();

  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Attaching to pid %i...", __FUNCTION__,
                   attach_pid);
  char err_str[1024];
  pid = DNBProcessAttach(attach_pid, NULL, err_str, sizeof(err_str));
  g_pid = pid;

  if (pid == INVALID_NUB_PROCESS) {
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    if (err_str[0])
      ctx.LaunchStatus().SetErrorString(err_str);
    return eRNBRunLoopModeExit;
  } else {
    ctx.SetProcessID(pid);
    return eRNBRunLoopModeInferiorExecuting;
  }
}

// Watch for signals:
// SIGINT: so we can halt our inferior. (disabled for now)
// SIGPIPE: in case our child process dies
int g_sigint_received = 0;
int g_sigpipe_received = 0;
void signal_handler(int signo) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__,
                   SysSignal::Name(signo));

  switch (signo) {
  case SIGINT:
    g_sigint_received++;
    if (g_pid != INVALID_NUB_PROCESS) {
      // Only send a SIGINT once...
      if (g_sigint_received == 1) {
        switch (DNBProcessGetState(g_pid)) {
        case eStateRunning:
        case eStateStepping:
          DNBProcessSignal(g_pid, SIGSTOP);
          return;
        default:
          break;
        }
      }
    }
    exit(SIGINT);
    break;

  case SIGPIPE:
    g_sigpipe_received = 1;
    break;
  }
}

// Return the new run loop mode based off of the current process state
RNBRunLoopMode HandleProcessStateChange(RNBRemote *remote, bool initialize) {
  RNBContext &ctx = remote->Context();
  nub_process_t pid = ctx.ProcessID();

  if (pid == INVALID_NUB_PROCESS) {
    DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...",
                     __FUNCTION__);
    return eRNBRunLoopModeExit;
  }
  nub_state_t pid_state = DNBProcessGetState(pid);

  DNBLogThreadedIf(LOG_RNB_MINIMAL,
                   "%s (&remote, initialize=%i)  pid_state = %s", __FUNCTION__,
                   (int)initialize, DNBStateAsString(pid_state));

  switch (pid_state) {
  case eStateInvalid:
  case eStateUnloaded:
    // Something bad happened
    return eRNBRunLoopModeExit;
    break;

  case eStateAttaching:
  case eStateLaunching:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateSuspended:
  case eStateCrashed:
  case eStateStopped:
    // If we stop due to a signal, so clear the fact that we got a SIGINT
    // so we can stop ourselves again (but only while our inferior
    // process is running..)
    g_sigint_received = 0;
    if (initialize == false) {
      // Compare the last stop count to our current notion of a stop count
      // to make sure we don't notify more than once for a given stop.
      nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
      bool pid_stop_count_changed =
          ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
      if (pid_stop_count_changed) {
        remote->FlushSTDIO();

        if (ctx.GetProcessStopCount() == 1) {
          DNBLogThreadedIf(
              LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                               "pid_stop_count %llu (old %llu)) Notify??? no, "
                               "first stop...",
              __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
              (uint64_t)ctx.GetProcessStopCount(),
              (uint64_t)prev_pid_stop_count);
        } else {

          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  "
                                            "pid_state = %s pid_stop_count "
                                            "%llu (old %llu)) Notify??? YES!!!",
                           __FUNCTION__, (int)initialize,
                           DNBStateAsString(pid_state),
                           (uint64_t)ctx.GetProcessStopCount(),
                           (uint64_t)prev_pid_stop_count);
          remote->NotifyThatProcessStopped();
        }
      } else {
        DNBLogThreadedIf(
            LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                             "pid_stop_count %llu (old %llu)) Notify??? "
                             "skipping...",
            __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
            (uint64_t)ctx.GetProcessStopCount(), (uint64_t)prev_pid_stop_count);
      }
    }
    return eRNBRunLoopModeInferiorExecuting;

  case eStateStepping:
  case eStateRunning:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateExited:
    remote->HandlePacket_last_signal(NULL);
    return eRNBRunLoopModeExit;
  case eStateDetached:
    return eRNBRunLoopModeExit;
  }

  // Catch all...
  return eRNBRunLoopModeExit;
}

// This function handles the case where our inferior program is stopped and
// we are waiting for gdb remote protocol packets. When a packet occurs that
// makes the inferior run, we need to leave this function with a new state
// as the return code.
RNBRunLoopMode RNBRunLoopInferiorExecuting(RNBRemote *remote) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
  RNBContext &ctx = remote->Context();

  // Init our mode and set 'is_running' based on the current process state
  RNBRunLoopMode mode = HandleProcessStateChange(remote, true);

  while (ctx.ProcessID() != INVALID_NUB_PROCESS) {

    std::string set_events_str;
    uint32_t event_mask = ctx.NormalEventBits();

    if (!ctx.ProcessStateRunning()) {
      // Clear some bits if we are not running so we don't send any async
      // packets
      event_mask &= ~RNBContext::event_proc_stdio_available;
      event_mask &= ~RNBContext::event_proc_profile_data;
      // When we enable async structured data packets over another logical
      // channel,
      // this can be relaxed.
      event_mask &= ~RNBContext::event_darwin_log_data_available;
    }

    // We want to make sure we consume all process state changes and have
    // whomever is notifying us to wait for us to reset the event bit before
    // continuing.
    // ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);

    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
                     __FUNCTION__, event_mask);
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
                     __FUNCTION__, event_mask, set_events,
                     ctx.EventsAsString(set_events, set_events_str));

    if (set_events) {
      if ((set_events & RNBContext::event_proc_thread_exiting) ||
          (set_events & RNBContext::event_proc_stdio_available)) {
        remote->FlushSTDIO();
      }

      if (set_events & RNBContext::event_proc_profile_data) {
        remote->SendAsyncProfileData();
      }

      if (set_events & RNBContext::event_darwin_log_data_available) {
        remote->SendAsyncDarwinLogData();
      }

      if (set_events & RNBContext::event_read_packet_available) {
        // handleReceivedPacket will take care of resetting the
        // event_read_packet_available events when there are no more...
        set_events ^= RNBContext::event_read_packet_available;

        if (ctx.ProcessStateRunning()) {
          if (remote->HandleAsyncPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        } else {
          if (remote->HandleReceivedPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        }
      }

      if (set_events & RNBContext::event_proc_state_changed) {
        mode = HandleProcessStateChange(remote, false);
        ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
        set_events ^= RNBContext::event_proc_state_changed;
      }

      if (set_events & RNBContext::event_proc_thread_exiting) {
        mode = eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_thread_exiting) {
        // Out remote packet receiving thread exited, exit for now.
        if (ctx.HasValidProcessID()) {
          // TODO: We should add code that will leave the current process
          // in its current state and listen for another connection...
          if (ctx.ProcessStateRunning()) {
            if (ctx.GetDetachOnError()) {
              DNBLog("debugserver's event read thread is exiting, detaching "
                     "from the inferior process.");
              DNBProcessDetach(ctx.ProcessID());
            } else {
              DNBLog("debugserver's event read thread is exiting, killing the "
                     "inferior process.");
              DNBProcessKill(ctx.ProcessID());
            }
          } else {
            if (ctx.GetDetachOnError()) {
              DNBLog("debugserver's event read thread is exiting, detaching "
                     "from the inferior process.");
              DNBProcessDetach(ctx.ProcessID());
            }
          }
        }
        mode = eRNBRunLoopModeExit;
      }
    }

    // Reset all event bits that weren't reset for now...
    if (set_events != 0)
      ctx.Events().ResetEvents(set_events);

    if (mode != eRNBRunLoopModeInferiorExecuting)
      break;
  }

  return mode;
}

RNBRunLoopMode RNBRunLoopPlatform(RNBRemote *remote) {
  RNBRunLoopMode mode = eRNBRunLoopModePlatformMode;
  RNBContext &ctx = remote->Context();

  while (mode == eRNBRunLoopModePlatformMode) {
    std::string set_events_str;
    const uint32_t event_mask = RNBContext::event_read_packet_available |
                                RNBContext::event_read_thread_exiting;

    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
                     __FUNCTION__, event_mask);
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
                     __FUNCTION__, event_mask, set_events,
                     ctx.EventsAsString(set_events, set_events_str));

    if (set_events) {
      if (set_events & RNBContext::event_read_packet_available) {
        if (remote->HandleReceivedPacket() == rnb_not_connected)
          mode = eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_thread_exiting) {
        mode = eRNBRunLoopModeExit;
      }
      ctx.Events().ResetEvents(set_events);
    }
  }
  return eRNBRunLoopModeExit;
}

// Convenience function to set up the remote listening port
// Returns 1 for success 0 for failure.

static void PortWasBoundCallbackUnixSocket(const void *baton, in_port_t port) {
  //::printf ("PortWasBoundCallbackUnixSocket (baton = %p, port = %u)\n", baton,
  //port);

  const char *unix_socket_name = (const char *)baton;

  if (unix_socket_name && unix_socket_name[0]) {
    // We were given a unix socket name to use to communicate the port
    // that we ended up binding to back to our parent process
    struct sockaddr_un saddr_un;
    int s = ::socket(AF_UNIX, SOCK_STREAM, 0);
    if (s < 0) {
      perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
      exit(1);
    }

    saddr_un.sun_family = AF_UNIX;
    ::strlcpy(saddr_un.sun_path, unix_socket_name,
              sizeof(saddr_un.sun_path) - 1);
    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
    saddr_un.sun_len = SUN_LEN(&saddr_un);

    if (::connect(s, (struct sockaddr *)&saddr_un,
                  static_cast<socklen_t>(SUN_LEN(&saddr_un))) < 0) {
      perror("error: connect (socket, &saddr_un, saddr_un_len)");
      exit(1);
    }

    //::printf ("connect () sucess!!\n");

    // We were able to connect to the socket, now write our PID so whomever
    // launched us will know this process's ID
    RNBLogSTDOUT("Listening to port %i...\n", port);

    char pid_str[64];
    const int pid_str_len = ::snprintf(pid_str, sizeof(pid_str), "%u", port);
    const ssize_t bytes_sent = ::send(s, pid_str, pid_str_len, 0);

    if (pid_str_len != bytes_sent) {
      perror("error: send (s, pid_str, pid_str_len, 0)");
      exit(1);
    }

    //::printf ("send () sucess!!\n");

    // We are done with the socket
    close(s);
  }
}

static void PortWasBoundCallbackNamedPipe(const void *baton, uint16_t port) {
  const char *named_pipe = (const char *)baton;
  if (named_pipe && named_pipe[0]) {
    int fd = ::open(named_pipe, O_WRONLY);
    if (fd > -1) {
      char port_str[64];
      const ssize_t port_str_len =
          ::snprintf(port_str, sizeof(port_str), "%u", port);
      // Write the port number as a C string with the NULL terminator
      ::write(fd, port_str, port_str_len + 1);
      close(fd);
    }
  }
}

static int ConnectRemote(RNBRemote *remote, const char *host, int port,
                         bool reverse_connect, const char *named_pipe_path,
                         const char *unix_socket_name) {
  if (!remote->Comm().IsConnected()) {
    if (reverse_connect) {
      if (port == 0) {
        DNBLogThreaded(
            "error: invalid port supplied for reverse connection: %i.\n", port);
        return 0;
      }
      if (remote->Comm().Connect(host, port) != rnb_success) {
        DNBLogThreaded("Failed to reverse connect to %s:%i.\n", host, port);
        return 0;
      }
    } else {
      if (port != 0)
        RNBLogSTDOUT("Listening to port %i for a connection from %s...\n", port,
                     host ? host : "127.0.0.1");
      if (unix_socket_name && unix_socket_name[0]) {
        if (remote->Comm().Listen(host, port, PortWasBoundCallbackUnixSocket,
                                  unix_socket_name) != rnb_success) {
          RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
          return 0;
        }
      } else {
        if (remote->Comm().Listen(host, port, PortWasBoundCallbackNamedPipe,
                                  named_pipe_path) != rnb_success) {
          RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
          return 0;
        }
      }
    }
    remote->StartReadRemoteDataThread();
  }
  return 1;
}

// ASL Logging callback that can be registered with DNBLogSetLogCallback
void ASLLogCallback(void *baton, uint32_t flags, const char *format,
                    va_list args) {
  if (format == NULL)
    return;
  static aslmsg g_aslmsg = NULL;
  if (g_aslmsg == NULL) {
    g_aslmsg = ::asl_new(ASL_TYPE_MSG);
    char asl_key_sender[PATH_MAX];
    snprintf(asl_key_sender, sizeof(asl_key_sender), "com.apple.%s-%s",
             DEBUGSERVER_PROGRAM_NAME, DEBUGSERVER_VERSION_STR);
    ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender);
  }

  int asl_level;
  if (flags & DNBLOG_FLAG_FATAL)
    asl_level = ASL_LEVEL_CRIT;
  else if (flags & DNBLOG_FLAG_ERROR)
    asl_level = ASL_LEVEL_ERR;
  else if (flags & DNBLOG_FLAG_WARNING)
    asl_level = ASL_LEVEL_WARNING;
  else if (flags & DNBLOG_FLAG_VERBOSE)
    asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_INFO;
  else
    asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_DEBUG;

  ::asl_vlog(NULL, g_aslmsg, asl_level, format, args);
}

// FILE based Logging callback that can be registered with
// DNBLogSetLogCallback
void FileLogCallback(void *baton, uint32_t flags, const char *format,
                     va_list args) {
  if (baton == NULL || format == NULL)
    return;

  ::vfprintf((FILE *)baton, format, args);
  ::fprintf((FILE *)baton, "\n");
  ::fflush((FILE *)baton);
}

void show_version_and_exit(int exit_code) {
  printf("%s-%s for %s.\n", DEBUGSERVER_PROGRAM_NAME, DEBUGSERVER_VERSION_STR,
         RNB_ARCH);
  exit(exit_code);
}

void show_usage_and_exit(int exit_code) {
  RNBLogSTDERR(
      "Usage:\n  %s host:port [program-name program-arg1 program-arg2 ...]\n",
      DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file [program-name program-arg1 program-arg2 ...]\n",
               DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s host:port --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s host:port --attach=<process_name>\n",
               DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file --attach=<process_name>\n",
               DEBUGSERVER_PROGRAM_NAME);
  exit(exit_code);
}

// option descriptors for getopt_long_only()
static struct option g_long_options[] = {
    {"attach", required_argument, NULL, 'a'},
    {"arch", required_argument, NULL, 'A'},
    {"debug", no_argument, NULL, 'g'},
    {"kill-on-error", no_argument, NULL, 'K'},
    {"verbose", no_argument, NULL, 'v'},
    {"version", no_argument, NULL, 'V'},
    {"lockdown", no_argument, &g_lockdown_opt, 1}, // short option "-k"
    {"applist", no_argument, &g_applist_opt, 1},   // short option "-t"
    {"log-file", required_argument, NULL, 'l'},
    {"log-flags", required_argument, NULL, 'f'},
    {"launch", required_argument, NULL, 'x'}, // Valid values are "auto",
                                              // "posix-spawn", "fork-exec",
                                              // "springboard" (arm only)
    {"waitfor", required_argument, NULL,
     'w'}, // Wait for a process whose name starts with ARG
    {"waitfor-interval", required_argument, NULL,
     'i'}, // Time in usecs to wait between sampling the pid list when waiting
           // for a process by name
    {"waitfor-duration", required_argument, NULL,
     'd'}, // The time in seconds to wait for a process to show up by name
    {"native-regs", no_argument, NULL, 'r'}, // Specify to use the native
                                             // registers instead of the gdb
                                             // defaults for the architecture.
    {"stdio-path", required_argument, NULL,
     's'}, // Set the STDIO path to be used when launching applications (STDIN,
           // STDOUT and STDERR) (only if debugserver launches the process)
    {"stdin-path", required_argument, NULL,
     'I'}, // Set the STDIN path to be used when launching applications (only if
           // debugserver launches the process)
    {"stdout-path", required_argument, NULL,
     'O'}, // Set the STDOUT path to be used when launching applications (only
           // if debugserver launches the process)
    {"stderr-path", required_argument, NULL,
     'E'}, // Set the STDERR path to be used when launching applications (only
           // if debugserver launches the process)
    {"no-stdio", no_argument, NULL,
     'n'}, // Do not set up any stdio (perhaps the program is a GUI program)
           // (only if debugserver launches the process)
    {"setsid", no_argument, NULL,
     'S'}, // call setsid() to make debugserver run in its own session
    {"disable-aslr", no_argument, NULL, 'D'}, // Use _POSIX_SPAWN_DISABLE_ASLR
                                              // to avoid shared library
                                              // randomization
    {"working-dir", required_argument, NULL,
     'W'}, // The working directory that the inferior process should have (only
           // if debugserver launches the process)
    {"platform", required_argument, NULL,
     'p'}, // Put this executable into a remote platform mode
    {"unix-socket", required_argument, NULL,
     'u'}, // If we need to handshake with our parent process, an option will be
           // passed down that specifies a unix socket name to use
    {"fd", required_argument, NULL,
     '2'}, // A file descriptor was passed to this process when spawned that
           // is already open and ready for communication
    {"named-pipe", required_argument, NULL, 'P'},
    {"reverse-connect", no_argument, NULL, 'R'},
    {"env", required_argument, NULL,
     'e'}, // When debugserver launches the process, set a single environment
           // entry as specified by the option value ("./debugserver -e FOO=1 -e
           // BAR=2 localhost:1234 -- /bin/ls")
    {"forward-env", no_argument, NULL,
     'F'}, // When debugserver launches the process, forward debugserver's
           // current environment variables to the child process ("./debugserver
           // -F localhost:1234 -- /bin/ls"
    {NULL, 0, NULL, 0}};

// main
int main(int argc, char *argv[]) {
  // If debugserver is launched with DYLD_INSERT_LIBRARIES, unset it so we
  // don't spawn child processes with this enabled.
  unsetenv("DYLD_INSERT_LIBRARIES");

  const char *argv_sub_zero =
      argv[0]; // save a copy of argv[0] for error reporting post-launch

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

  ::proc_set_wakemon_params(
      getpid(), 500,
      0); // Allow up to 500 wakeups/sec to avoid EXC_RESOURCE for normal use.
#endif
#endif

  g_isatty = ::isatty(STDIN_FILENO);

  //  ::printf ("uid=%u euid=%u gid=%u egid=%u\n",
  //            getuid(),
  //            geteuid(),
  //            getgid(),
  //            getegid());

  //    signal (SIGINT, signal_handler);
  signal(SIGPIPE, signal_handler);
  signal(SIGHUP, signal_handler);

  // We're always sitting in waitpid or kevent waiting on our target process'
  // death,
  // we don't need no stinking SIGCHLD's...

  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGCHLD);
  sigprocmask(SIG_BLOCK, &sigset, NULL);

  g_remoteSP = std::make_shared<RNBRemote>();

  RNBRemote *remote = g_remoteSP.get();
  if (remote == NULL) {
    RNBLogSTDERR("error: failed to create a remote connection class\n");
    return -1;
  }

  RNBContext &ctx = remote->Context();

  int i;
  int attach_pid = INVALID_NUB_PROCESS;

  FILE *log_file = NULL;
  uint32_t log_flags = 0;
  // Parse our options
  int ch;
  int long_option_index = 0;
  int debug = 0;
  int communication_fd = -1;
  std::string compile_options;
  std::string waitfor_pid_name; // Wait for a process that starts with this name
  std::string attach_pid_name;
  std::string arch_name;
  std::string working_dir; // The new working directory to use for the inferior
  std::string unix_socket_name; // If we need to handshake with our parent
                                // process, an option will be passed down that
                                // specifies a unix socket name to use
  std::string named_pipe_path;  // If we need to handshake with our parent
                                // process, an option will be passed down that
                                // specifies a named pipe to use
  useconds_t waitfor_interval = 1000; // Time in usecs between process lists
                                      // polls when waiting for a process by
                                      // name, default 1 msec.
  useconds_t waitfor_duration =
      0; // Time in seconds to wait for a process by name, 0 means wait forever.
  bool no_stdio = false;
  bool reverse_connect = false; // Set to true by an option to indicate we
                                // should reverse connect to the host:port
                                // supplied as the first debugserver argument

#if !defined(DNBLOG_ENABLED)
  compile_options += "(no-logging) ";
#endif

  RNBRunLoopMode start_mode = eRNBRunLoopModeExit;

  char short_options[512];
  uint32_t short_options_idx = 0;

  // Handle the two case that don't have short options in g_long_options
  short_options[short_options_idx++] = 'k';
  short_options[short_options_idx++] = 't';

  for (i = 0; g_long_options[i].name != NULL; ++i) {
    if (isalpha(g_long_options[i].val)) {
      short_options[short_options_idx++] = g_long_options[i].val;
      switch (g_long_options[i].has_arg) {
      default:
      case no_argument:
        break;

      case optional_argument:
        short_options[short_options_idx++] = ':';
        short_options[short_options_idx++] = ':';
        break;
      case required_argument:
        short_options[short_options_idx++] = ':';
        break;
      }
    }
  }
  // NULL terminate the short option string.
  short_options[short_options_idx++] = '\0';

#if __GLIBC__
  optind = 0;
#else
  optreset = 1;
  optind = 1;
#endif

  bool forward_env = false;
  while ((ch = getopt_long_only(argc, argv, short_options, g_long_options,
                                &long_option_index)) != -1) {
    DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch,
                g_long_options[long_option_index].name,
                g_long_options[long_option_index].has_arg ? '=' : ' ',
                optarg ? optarg : "");
    switch (ch) {
    case 0: // Any optional that auto set themselves will return 0
      break;

    case 'A':
      if (optarg && optarg[0])
        arch_name.assign(optarg);
      break;

    case 'a':
      if (optarg && optarg[0]) {
        if (isdigit(optarg[0])) {
          char *end = NULL;
          attach_pid = static_cast<int>(strtoul(optarg, &end, 0));
          if (end == NULL || *end != '\0') {
            RNBLogSTDERR("error: invalid pid option '%s'\n", optarg);
            exit(4);
          }
        } else {
          attach_pid_name = optarg;
        }
        start_mode = eRNBRunLoopModeInferiorAttaching;
      }
      break;

    // --waitfor=NAME
    case 'w':
      if (optarg && optarg[0]) {
        waitfor_pid_name = optarg;
        start_mode = eRNBRunLoopModeInferiorAttaching;
      }
      break;

    // --waitfor-interval=USEC
    case 'i':
      if (optarg && optarg[0]) {
        char *end = NULL;
        waitfor_interval = static_cast<useconds_t>(strtoul(optarg, &end, 0));
        if (end == NULL || *end != '\0') {
          RNBLogSTDERR("error: invalid waitfor-interval option value '%s'.\n",
                       optarg);
          exit(6);
        }
      }
      break;

    // --waitfor-duration=SEC
    case 'd':
      if (optarg && optarg[0]) {
        char *end = NULL;
        waitfor_duration = static_cast<useconds_t>(strtoul(optarg, &end, 0));
        if (end == NULL || *end != '\0') {
          RNBLogSTDERR("error: invalid waitfor-duration option value '%s'.\n",
                       optarg);
          exit(7);
        }
      }
      break;

    case 'K':
      g_detach_on_error = false;
      break;
    case 'W':
      if (optarg && optarg[0])
        working_dir.assign(optarg);
      break;

    case 'x':
      if (optarg && optarg[0]) {
        if (strcasecmp(optarg, "auto") == 0)
          g_launch_flavor = eLaunchFlavorDefault;
        else if (strcasestr(optarg, "posix") == optarg)
          g_launch_flavor = eLaunchFlavorPosixSpawn;
        else if (strcasestr(optarg, "fork") == optarg)
          g_launch_flavor = eLaunchFlavorForkExec;
#ifdef WITH_SPRINGBOARD
        else if (strcasestr(optarg, "spring") == optarg)
          g_launch_flavor = eLaunchFlavorSpringBoard;
#endif
#ifdef WITH_BKS
        else if (strcasestr(optarg, "backboard") == optarg)
          g_launch_flavor = eLaunchFlavorBKS;
#endif
#ifdef WITH_FBS
        else if (strcasestr(optarg, "frontboard") == optarg)
          g_launch_flavor = eLaunchFlavorFBS;
#endif

        else {
          RNBLogSTDERR("error: invalid TYPE for the --launch=TYPE (-x TYPE) "
                       "option: '%s'\n",
                       optarg);
          RNBLogSTDERR("Valid values TYPE are:\n");
          RNBLogSTDERR(
              "  auto       Auto-detect the best launch method to use.\n");
          RNBLogSTDERR(
              "  posix      Launch the executable using posix_spawn.\n");
          RNBLogSTDERR(
              "  fork       Launch the executable using fork and exec.\n");
#ifdef WITH_SPRINGBOARD
          RNBLogSTDERR(
              "  spring     Launch the executable through Springboard.\n");
#endif
#ifdef WITH_BKS
          RNBLogSTDERR("  backboard  Launch the executable through BackBoard "
                       "Services.\n");
#endif
#ifdef WITH_FBS
          RNBLogSTDERR("  frontboard  Launch the executable through FrontBoard "
                       "Services.\n");
#endif
          exit(5);
        }
      }
      break;

    case 'l': // Set Log File
      if (optarg && optarg[0]) {
        if (strcasecmp(optarg, "stdout") == 0)
          log_file = stdout;
        else if (strcasecmp(optarg, "stderr") == 0)
          log_file = stderr;
        else {
          log_file = fopen(optarg, "w");
          if (log_file != NULL)
            setlinebuf(log_file);
        }

        if (log_file == NULL) {
          const char *errno_str = strerror(errno);
          RNBLogSTDERR(
              "Failed to open log file '%s' for writing: errno = %i (%s)",
              optarg, errno, errno_str ? errno_str : "unknown error");
        }
      }
      break;

    case 'f': // Log Flags
      if (optarg && optarg[0])
        log_flags = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
      break;

    case 'g':
      debug = 1;
      DNBLogSetDebug(debug);
      break;

    case 't':
      g_applist_opt = 1;
      break;

    case 'k':
      g_lockdown_opt = 1;
      break;

    case 'r':
      // Do nothing, native regs is the default these days
      break;

    case 'R':
      reverse_connect = true;
      break;
    case 'v':
      DNBLogSetVerbose(1);
      break;

    case 'V':
      show_version_and_exit(0);
      break;

    case 's':
      ctx.GetSTDIN().assign(optarg);
      ctx.GetSTDOUT().assign(optarg);
      ctx.GetSTDERR().assign(optarg);
      break;

    case 'I':
      ctx.GetSTDIN().assign(optarg);
      break;

    case 'O':
      ctx.GetSTDOUT().assign(optarg);
      break;

    case 'E':
      ctx.GetSTDERR().assign(optarg);
      break;

    case 'n':
      no_stdio = true;
      break;

    case 'S':
      // Put debugserver into a new session. Terminals group processes
      // into sessions and when a special terminal key sequences
      // (like control+c) are typed they can cause signals to go out to
      // all processes in a session. Using this --setsid (-S) option
      // will cause debugserver to run in its own sessions and be free
      // from such issues.
      //
      // This is useful when debugserver is spawned from a command
      // line application that uses debugserver to do the debugging,
      // yet that application doesn't want debugserver receiving the
      // signals sent to the session (i.e. dying when anyone hits ^C).
      setsid();
      break;
    case 'D':
      g_disable_aslr = 1;
      break;

    case 'p':
      start_mode = eRNBRunLoopModePlatformMode;
      break;

    case 'u':
      unix_socket_name.assign(optarg);
      break;

    case 'P':
      named_pipe_path.assign(optarg);
      break;

    case 'e':
      // Pass a single specified environment variable down to the process that
      // gets launched
      remote->Context().PushEnvironment(optarg);
      break;

    case 'F':
      forward_env = true;
      break;

    case '2':
      // File descriptor passed to this process during fork/exec and is already
      // open and ready for communication.
      communication_fd = atoi(optarg);
      break;
    }
  }

  if (arch_name.empty()) {
#if defined(__arm__)
    arch_name.assign("arm");
#endif
  } else {
    DNBSetArchitecture(arch_name.c_str());
  }

  //    if (arch_name.empty())
  //    {
  //        fprintf(stderr, "error: no architecture was specified\n");
  //        exit (8);
  //    }
  // Skip any options we consumed with getopt_long_only
  argc -= optind;
  argv += optind;

  if (!working_dir.empty()) {
    if (remote->Context().SetWorkingDirectory(working_dir.c_str()) == false) {
      RNBLogSTDERR("error: working directory doesn't exist '%s'.\n",
                   working_dir.c_str());
      exit(8);
    }
  }

  remote->Context().SetDetachOnError(g_detach_on_error);

  remote->Initialize();

  // It is ok for us to set NULL as the logfile (this will disable any logging)

  if (log_file != NULL) {
    DNBLogSetLogCallback(FileLogCallback, log_file);
    // If our log file was set, yet we have no log flags, log everything!
    if (log_flags == 0)
      log_flags = LOG_ALL | LOG_RNB_ALL;

    DNBLogSetLogMask(log_flags);
  } else {
    // Enable DNB logging

    // if os_log() support is available, log through that.
    auto log_callback = OsLogger::GetLogFunction();
    if (log_callback) {
      DNBLogSetLogCallback(log_callback, nullptr);
      DNBLog("debugserver will use os_log for internal logging.");
    } else {
      // Fall back to ASL support.
      DNBLogSetLogCallback(ASLLogCallback, NULL);
      DNBLog("debugserver will use ASL for internal logging.");
    }
    DNBLogSetLogMask(log_flags);
  }

  if (DNBLogEnabled()) {
    for (i = 0; i < argc; i++)
      DNBLogDebug("argv[%i] = %s", i, argv[i]);
  }

  // as long as we're dropping remotenub in as a replacement for gdbserver,
  // explicitly note that this is not gdbserver.

  RNBLogSTDOUT("%s-%s %sfor %s.\n", DEBUGSERVER_PROGRAM_NAME,
               DEBUGSERVER_VERSION_STR, compile_options.c_str(), RNB_ARCH);

  std::string host;
  int port = INT32_MAX;
  char str[PATH_MAX];
  str[0] = '\0';

  if (g_lockdown_opt == 0 && g_applist_opt == 0 && communication_fd == -1) {
    // Make sure we at least have port
    if (argc < 1) {
      show_usage_and_exit(1);
    }
    // accept 'localhost:' prefix on port number
    std::string host_specifier = argv[0];
    auto colon_location = host_specifier.rfind(':');
    if (colon_location != std::string::npos) {
      host = host_specifier.substr(0, colon_location);
      std::string port_str =
          host_specifier.substr(colon_location + 1, std::string::npos);
      char *end_ptr;
      port = strtoul(port_str.c_str(), &end_ptr, 0);
      if (end_ptr < port_str.c_str() + port_str.size())
        show_usage_and_exit(2);
      if (host.front() == '[' && host.back() == ']')
        host = host.substr(1, host.size() - 2);
      DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
    } else {
      // No hostname means "localhost"
      int items_scanned = ::sscanf(argv[0], "%i", &port);
      if (items_scanned == 1) {
        host = "127.0.0.1";
        DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
      } else if (argv[0][0] == '/') {
        port = INT32_MAX;
        strlcpy(str, argv[0], sizeof(str));
      } else {
        show_usage_and_exit(2);
      }
    }

    // We just used the 'host:port' or the '/path/file' arg...
    argc--;
    argv++;
  }

  //  If we know we're waiting to attach, we don't need any of this other info.
  if (start_mode != eRNBRunLoopModeInferiorAttaching &&
      start_mode != eRNBRunLoopModePlatformMode) {
    if (argc == 0 || g_lockdown_opt) {
      if (g_lockdown_opt != 0) {
        // Work around for SIGPIPE crashes due to posix_spawn issue.
        // We have to close STDOUT and STDERR, else the first time we
        // try and do any, we get SIGPIPE and die as posix_spawn is
        // doing bad things with our file descriptors at the moment.
        int null = open("/dev/null", O_RDWR);
        dup2(null, STDOUT_FILENO);
        dup2(null, STDERR_FILENO);
      } else if (g_applist_opt != 0) {
        // List all applications we are able to see
        std::string applist_plist;
        int err = ListApplications(applist_plist, false, false);
        if (err == 0) {
          fputs(applist_plist.c_str(), stdout);
        } else {
          RNBLogSTDERR("error: ListApplications returned error %i\n", err);
        }
        // Exit with appropriate error if we were asked to list the applications
        // with no other args were given (and we weren't trying to do this over
        // lockdown)
        return err;
      }

      DNBLogDebug("Get args from remote protocol...");
      start_mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;
    } else {
      start_mode = eRNBRunLoopModeInferiorLaunching;
      // Fill in the argv array in the context from the rest of our args.
      // Skip the name of this executable and the port number
      for (int i = 0; i < argc; i++) {
        DNBLogDebug("inferior_argv[%i] = '%s'", i, argv[i]);
        ctx.PushArgument(argv[i]);
      }
    }
  }

  if (start_mode == eRNBRunLoopModeExit)
    return -1;

  if (forward_env || start_mode == eRNBRunLoopModeInferiorLaunching) {
    // Pass the current environment down to the process that gets launched
    // This happens automatically in the "launching" mode. For the rest, we
    // only do that if the user explicitly requested this via --forward-env
    // argument.
    char **host_env = *_NSGetEnviron();
    char *env_entry;
    size_t i;
    for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
      remote->Context().PushEnvironmentIfNeeded(env_entry);
  }

  RNBRunLoopMode mode = start_mode;
  char err_str[1024] = {'\0'};

  while (mode != eRNBRunLoopModeExit) {
    switch (mode) {
    case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
#ifdef WITH_LOCKDOWN
      if (g_lockdown_opt) {
        if (!remote->Comm().IsConnected()) {
          if (remote->Comm().ConnectToService() != rnb_success) {
            RNBLogSTDERR(
                "Failed to get connection from a remote gdb process.\n");
            mode = eRNBRunLoopModeExit;
          } else if (g_applist_opt != 0) {
            // List all applications we are able to see
            std::string applist_plist;
            if (ListApplications(applist_plist, false, false) == 0) {
              DNBLogDebug("Task list: %s", applist_plist.c_str());

              remote->Comm().Write(applist_plist.c_str(), applist_plist.size());
              // Issue a read that will never yield any data until the other
              // side
              // closes the socket so this process doesn't just exit and cause
              // the
              // socket to close prematurely on the other end and cause data
              // loss.
              std::string buf;
              remote->Comm().Read(buf);
            }
            remote->Comm().Disconnect(false);
            mode = eRNBRunLoopModeExit;
            break;
          } else {
            // Start watching for remote packets
            remote->StartReadRemoteDataThread();
          }
        }
      } else
#endif
          if (port != INT32_MAX) {
        if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                           named_pipe_path.c_str(), unix_socket_name.c_str()))
          mode = eRNBRunLoopModeExit;
      } else if (str[0] == '/') {
        if (remote->Comm().OpenFile(str))
          mode = eRNBRunLoopModeExit;
      } else if (communication_fd >= 0) {
        // We were passed a file descriptor to use during fork/exec that is
        // already open
        // in our process, so lets just use it!
        if (remote->Comm().useFD(communication_fd))
          mode = eRNBRunLoopModeExit;
        else
          remote->StartReadRemoteDataThread();
      }

      if (mode != eRNBRunLoopModeExit) {
        RNBLogSTDOUT("Got a connection, waiting for process information for "
                     "launching or attaching.\n");

        mode = RNBRunLoopGetStartModeFromRemote(remote);
      }
      break;

    case eRNBRunLoopModeInferiorAttaching:
      if (!waitfor_pid_name.empty()) {
        // Set our end wait time if we are using a waitfor-duration
        // option that may have been specified
        struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
        if (waitfor_duration != 0) {
          DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
                                    0);
          timeout_ptr = &attach_timeout_abstime;
        }
        nub_launch_flavor_t launch_flavor = g_launch_flavor;
        if (launch_flavor == eLaunchFlavorDefault) {
          // Our default launch method is posix spawn
          launch_flavor = eLaunchFlavorPosixSpawn;

#if defined WITH_FBS
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorFBS;
          }
#elif defined WITH_BKS
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorBKS;
          }
#elif defined WITH_SPRINGBOARD
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorSpringBoard;
          }
#endif
        }

        ctx.SetLaunchFlavor(launch_flavor);
        bool ignore_existing = false;
        RNBLogSTDOUT("Waiting to attach to process %s...\n",
                     waitfor_pid_name.c_str());
        nub_process_t pid = DNBProcessAttachWait(
            waitfor_pid_name.c_str(), launch_flavor, ignore_existing,
            timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
        g_pid = pid;

        if (pid == INVALID_NUB_PROCESS) {
          ctx.LaunchStatus().SetError(-1, DNBError::Generic);
          if (err_str[0])
            ctx.LaunchStatus().SetErrorString(err_str);
          RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
                       waitfor_pid_name.c_str(), err_str);
          mode = eRNBRunLoopModeExit;
        } else {
          ctx.SetProcessID(pid);
          mode = eRNBRunLoopModeInferiorExecuting;
        }
      } else if (attach_pid != INVALID_NUB_PROCESS) {

        RNBLogSTDOUT("Attaching to process %i...\n", attach_pid);
        nub_process_t attached_pid;
        mode = RNBRunLoopLaunchAttaching(remote, attach_pid, attached_pid);
        if (mode != eRNBRunLoopModeInferiorExecuting) {
          const char *error_str = remote->Context().LaunchStatus().AsString();
          RNBLogSTDERR("error: failed to attach process %i: %s\n", attach_pid,
                       error_str ? error_str : "unknown error.");
          mode = eRNBRunLoopModeExit;
        }
      } else if (!attach_pid_name.empty()) {
        struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
        if (waitfor_duration != 0) {
          DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
                                    0);
          timeout_ptr = &attach_timeout_abstime;
        }

        RNBLogSTDOUT("Attaching to process %s...\n", attach_pid_name.c_str());
        nub_process_t pid = DNBProcessAttachByName(
            attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
        g_pid = pid;
        if (pid == INVALID_NUB_PROCESS) {
          ctx.LaunchStatus().SetError(-1, DNBError::Generic);
          if (err_str[0])
            ctx.LaunchStatus().SetErrorString(err_str);
          RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
                       waitfor_pid_name.c_str(), err_str);
          mode = eRNBRunLoopModeExit;
        } else {
          ctx.SetProcessID(pid);
          mode = eRNBRunLoopModeInferiorExecuting;
        }

      } else {
        RNBLogSTDERR(
            "error: asked to attach with empty name and invalid PID.\n");
        mode = eRNBRunLoopModeExit;
      }

      if (mode != eRNBRunLoopModeExit) {
        if (port != INT32_MAX) {
          if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                             named_pipe_path.c_str(), unix_socket_name.c_str()))
            mode = eRNBRunLoopModeExit;
        } else if (str[0] == '/') {
          if (remote->Comm().OpenFile(str))
            mode = eRNBRunLoopModeExit;
        } else if (communication_fd >= 0) {
          // We were passed a file descriptor to use during fork/exec that is
          // already open
          // in our process, so lets just use it!
          if (remote->Comm().useFD(communication_fd))
            mode = eRNBRunLoopModeExit;
          else
            remote->StartReadRemoteDataThread();
        }

        if (mode != eRNBRunLoopModeExit)
          RNBLogSTDOUT("Waiting for debugger instructions for process %d.\n",
                       attach_pid);
      }
      break;

    case eRNBRunLoopModeInferiorLaunching: {
      mode = RNBRunLoopLaunchInferior(remote, ctx.GetSTDINPath(),
                                      ctx.GetSTDOUTPath(), ctx.GetSTDERRPath(),
                                      no_stdio);

      if (mode == eRNBRunLoopModeInferiorExecuting) {
        if (port != INT32_MAX) {
          if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                             named_pipe_path.c_str(), unix_socket_name.c_str()))
            mode = eRNBRunLoopModeExit;
        } else if (str[0] == '/') {
          if (remote->Comm().OpenFile(str))
            mode = eRNBRunLoopModeExit;
        } else if (communication_fd >= 0) {
          // We were passed a file descriptor to use during fork/exec that is
          // already open
          // in our process, so lets just use it!
          if (remote->Comm().useFD(communication_fd))
            mode = eRNBRunLoopModeExit;
          else
            remote->StartReadRemoteDataThread();
        }

        if (mode != eRNBRunLoopModeExit) {
          const char *proc_name = "<unknown>";
          if (ctx.ArgumentCount() > 0)
            proc_name = ctx.ArgumentAtIndex(0);
          RNBLogSTDOUT("Got a connection, launched process %s (pid = %d).\n",
                       proc_name, ctx.ProcessID());
        }
      } else {
        const char *error_str = remote->Context().LaunchStatus().AsString();
        RNBLogSTDERR("error: failed to launch process %s: %s\n", argv_sub_zero,
                     error_str ? error_str : "unknown error.");
      }
    } break;

    case eRNBRunLoopModeInferiorExecuting:
      mode = RNBRunLoopInferiorExecuting(remote);
      break;

    case eRNBRunLoopModePlatformMode:
      if (port != INT32_MAX) {
        if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                           named_pipe_path.c_str(), unix_socket_name.c_str()))
          mode = eRNBRunLoopModeExit;
      } else if (str[0] == '/') {
        if (remote->Comm().OpenFile(str))
          mode = eRNBRunLoopModeExit;
      } else if (communication_fd >= 0) {
        // We were passed a file descriptor to use during fork/exec that is
        // already open
        // in our process, so lets just use it!
        if (remote->Comm().useFD(communication_fd))
          mode = eRNBRunLoopModeExit;
        else
          remote->StartReadRemoteDataThread();
      }

      if (mode != eRNBRunLoopModeExit)
        mode = RNBRunLoopPlatform(remote);
      break;

    default:
      mode = eRNBRunLoopModeExit;
      break;
    case eRNBRunLoopModeExit:
      break;
    }
  }

  remote->StopReadRemoteDataThread();
  remote->Context().SetProcessID(INVALID_NUB_PROCESS);
  RNBLogSTDOUT("Exiting.\n");

  return 0;
}
