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

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

#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 "PseudoTerminal.h"
#include "RNBContext.h"
#include "RNBServices.h"
#include "RNBSocket.h"
#include "RNBRemote.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
//----------------------------------------------------------------------
typedef enum
{
    eRNBRunLoopModeInvalid = 0,
    eRNBRunLoopModeGetStartModeFromRemoteProtocol,
    eRNBRunLoopModeInferiorAttaching,
    eRNBRunLoopModeInferiorLaunching,
    eRNBRunLoopModeInferiorExecuting,
    eRNBRunLoopModePlatformMode,
    eRNBRunLoopModeExit
} RNBRunLoopMode;


//----------------------------------------------------------------------
// 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 (1)
        {
            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)) )
        ::strncpy(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);
        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;
        }

        // 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_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;
        ::strncpy(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");
}


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' },
    { "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
    { "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[])
{
    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.reset (new 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++] = ':';
                    // Fall through to required_argument case below...
                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

    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;

            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 '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':
                // Pass the current environment down to the process that gets launched
                {
                    char **host_env = *_NSGetEnviron();
                    char *env_entry;
                    size_t i;
                    for (i=0; (env_entry = host_env[i]) != NULL; ++i)
                        remote->Context().PushEnvironment(env_entry);
                }
                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
        DNBLogSetLogCallback(ASLLogCallback, NULL);
        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)
    {
        // Make sure we at least have port
        if (argc < 1)
        {
            show_usage_and_exit (1);
        }
        // accept 'localhost:' prefix on port number

        int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &port);
        if (items_scanned == 2)
        {
            host = str;
            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;
                strncpy(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;

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

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

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

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

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

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

    return 0;
}
