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

static nub_launch_flavor_t default_launch_flavor(const char *app_name) {
#if defined(WITH_FBS) || defined(WITH_BKS) || defined(WITH_SPRINGBOARD)
  // Check the name to see if it ends with .app
  auto is_dot_app = [](const char *app_name) {
    size_t len = strlen(app_name);
    if (len < 4)
      return false;

    if (app_name[len - 4] == '.' && app_name[len - 3] == 'a' &&
        app_name[len - 2] == 'p' && app_name[len - 1] == 'p')
      return true;
    return false;
  };

  if (is_dot_app(app_name)) {
#if defined WITH_FBS
    // Check if we have an app bundle, if so launch using FrontBoard Services.
    return eLaunchFlavorFBS;
#elif defined WITH_BKS
    // Check if we have an app bundle, if so launch using BackBoard Services.
    return eLaunchFlavorBKS;
#elif defined WITH_SPRINGBOARD
    // Check if we have an app bundle, if so launch using SpringBoard.
    return eLaunchFlavorSpringBoard;
#endif
  }
#endif

  // Our default launch method is posix spawn
  return eLaunchFlavorPosixSpawn;
}

// 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)
    launch_flavor = default_launch_flavor(inferior_argv[0]);

  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(
      &ctx, resolved_path, &inferior_argv[0], &inferior_envp[0], cwd,
      stdin_path, stdout_path, stderr_path, no_stdio, 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, ctx.GetUnmaskSignals(), 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"
    {"unmask-signals", no_argument, NULL,
     'U'}, // debugserver will ignore EXC_MASK_BAD_ACCESS,
           // EXC_MASK_BAD_INSTRUCTION and EXC_MASK_ARITHMETIC, which results in
           // SIGSEGV, SIGILL and SIGFPE being propagated to the target process.
    {NULL, 0, NULL, 0}};

int communication_fd = -1;

// 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;
  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 'U':
      ctx.SetUnmaskSignals(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)
          launch_flavor = default_launch_flavor(waitfor_pid_name.c_str());

        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(
            &ctx, waitfor_pid_name.c_str(), 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, ctx.GetUnmaskSignals(),
            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;
}
