diff --git a/lldb/tools/debugserver/source/RNBContext.cpp b/lldb/tools/debugserver/source/RNBContext.cpp
index 0b44fdb..483cdf9 100644
--- a/lldb/tools/debugserver/source/RNBContext.cpp
+++ b/lldb/tools/debugserver/source/RNBContext.cpp
@@ -13,269 +13,266 @@
 
 #include "RNBContext.h"
 
-#include <sys/stat.h>
 #include <sstream>
+#include <sys/stat.h>
 
-#if defined (__APPLE__)
+#if defined(__APPLE__)
 #include <pthread.h>
 #include <sched.h>
 #endif
 
-#include "RNBRemote.h"
+#include "CFString.h"
 #include "DNB.h"
 #include "DNBLog.h"
-#include "CFString.h"
-
+#include "RNBRemote.h"
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-RNBContext::~RNBContext()
-{
-    SetProcessID (INVALID_NUB_PROCESS);
-}
+RNBContext::~RNBContext() { SetProcessID(INVALID_NUB_PROCESS); }
 
 //----------------------------------------------------------------------
 // RNBContext constructor
 //----------------------------------------------------------------------
 
-const char *
-RNBContext::EnvironmentAtIndex (size_t index)
-{
-    if (index < m_env_vec.size())
-        return m_env_vec[index].c_str();
-    else
-        return NULL;
+const char *RNBContext::EnvironmentAtIndex(size_t index) {
+  if (index < m_env_vec.size())
+    return m_env_vec[index].c_str();
+  else
+    return NULL;
 }
 
-
-const char *
-RNBContext::ArgumentAtIndex (size_t index)
-{
-    if (index < m_arg_vec.size())
-        return m_arg_vec[index].c_str();
-    else
-        return NULL;
+const char *RNBContext::ArgumentAtIndex(size_t index) {
+  if (index < m_arg_vec.size())
+    return m_arg_vec[index].c_str();
+  else
+    return NULL;
 }
 
-bool
-RNBContext::SetWorkingDirectory (const char *path)
-{
-    struct stat working_directory_stat;
-    if (::stat (path, &working_directory_stat) != 0)
-    {
-        m_working_directory.clear();
-        return false;
-    }
-    m_working_directory.assign(path);
-    return true;
+bool RNBContext::SetWorkingDirectory(const char *path) {
+  struct stat working_directory_stat;
+  if (::stat(path, &working_directory_stat) != 0) {
+    m_working_directory.clear();
+    return false;
+  }
+  m_working_directory.assign(path);
+  return true;
 }
 
+void RNBContext::SetProcessID(nub_process_t pid) {
+  // Delete and events we created
+  if (m_pid != INVALID_NUB_PROCESS) {
+    StopProcessStatusThread();
+    // Unregister this context as a client of the process's events.
+  }
+  // Assign our new process ID
+  m_pid = pid;
 
-void
-RNBContext::SetProcessID (nub_process_t pid)
-{
-    // Delete and events we created
-    if (m_pid != INVALID_NUB_PROCESS)
-    {
-        StopProcessStatusThread ();
-        // Unregister this context as a client of the process's events.
-    }
-    // Assign our new process ID
-    m_pid = pid;
-
-    if (pid != INVALID_NUB_PROCESS)
-    {
-        StartProcessStatusThread ();
-    }
+  if (pid != INVALID_NUB_PROCESS) {
+    StartProcessStatusThread();
+  }
 }
 
-void
-RNBContext::StartProcessStatusThread()
-{
-    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
-    if ((m_events.GetEventBits() & event_proc_thread_running) == 0)
-    {
-        int err = ::pthread_create (&m_pid_pthread, NULL, ThreadFunctionProcessStatus, this);
-        if (err == 0)
-        {
-            // Our thread was successfully kicked off, wait for it to
-            // set the started event so we can safely continue
-            m_events.WaitForSetEvents (event_proc_thread_running);
-            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread got started!", __FUNCTION__);
-        }
-        else
-        {
-            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread failed to start: err = %i", __FUNCTION__, err);
-            m_events.ResetEvents (event_proc_thread_running);
-            m_events.SetEvents (event_proc_thread_exiting);
-        }
+void RNBContext::StartProcessStatusThread() {
+  DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
+  if ((m_events.GetEventBits() & event_proc_thread_running) == 0) {
+    int err = ::pthread_create(&m_pid_pthread, NULL,
+                               ThreadFunctionProcessStatus, this);
+    if (err == 0) {
+      // Our thread was successfully kicked off, wait for it to
+      // set the started event so we can safely continue
+      m_events.WaitForSetEvents(event_proc_thread_running);
+      DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread got started!",
+                       __FUNCTION__);
+    } else {
+      DNBLogThreadedIf(LOG_RNB_PROC,
+                       "RNBContext::%s thread failed to start: err = %i",
+                       __FUNCTION__, err);
+      m_events.ResetEvents(event_proc_thread_running);
+      m_events.SetEvents(event_proc_thread_exiting);
     }
+  }
 }
 
-void
-RNBContext::StopProcessStatusThread()
-{
-    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
-    if ((m_events.GetEventBits() & event_proc_thread_running) == event_proc_thread_running)
-    {
-        struct timespec timeout_abstime;
-        DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
-        // Wait for 2 seconds for the rx thread to exit
-        if (m_events.WaitForSetEvents(RNBContext::event_proc_thread_exiting, &timeout_abstime) == RNBContext::event_proc_thread_exiting)
-        {
-            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread stopped as requeseted", __FUNCTION__);
-        }
-        else
-        {
-            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread did not stop in 2 seconds...", __FUNCTION__);
-            // Kill the RX thread???
-        }
+void RNBContext::StopProcessStatusThread() {
+  DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
+  if ((m_events.GetEventBits() & event_proc_thread_running) ==
+      event_proc_thread_running) {
+    struct timespec timeout_abstime;
+    DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
+    // Wait for 2 seconds for the rx thread to exit
+    if (m_events.WaitForSetEvents(RNBContext::event_proc_thread_exiting,
+                                  &timeout_abstime) ==
+        RNBContext::event_proc_thread_exiting) {
+      DNBLogThreadedIf(LOG_RNB_PROC,
+                       "RNBContext::%s thread stopped as requeseted",
+                       __FUNCTION__);
+    } else {
+      DNBLogThreadedIf(LOG_RNB_PROC,
+                       "RNBContext::%s thread did not stop in 2 seconds...",
+                       __FUNCTION__);
+      // Kill the RX thread???
     }
+  }
 }
 
 //----------------------------------------------------------------------
 // This thread's sole purpose is to watch for any status changes in the
 // child process.
 //----------------------------------------------------------------------
-void*
-RNBContext::ThreadFunctionProcessStatus(void *arg)
-{
-    RNBRemoteSP remoteSP(g_remoteSP);
-    RNBRemote* remote = remoteSP.get();
-    if (remote == NULL)
-        return NULL;
-    RNBContext& ctx = remote->Context();
-
-    nub_process_t pid = ctx.ProcessID();
-    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (arg=%p, pid=%4.4x): thread starting...", __FUNCTION__, arg, pid);
-    ctx.Events().SetEvents (RNBContext::event_proc_thread_running);
-
-#if defined (__APPLE__)
-    pthread_setname_np ("child process status watcher 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);
-    }
-#endif
-#endif
-
-    bool done = false;
-    while (!done)
-    {
-        DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true)...", __FUNCTION__);
-        nub_event_t pid_status_event = DNBProcessWaitForEvents (pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true, NULL);
-        DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true) => 0x%8.8x", __FUNCTION__, pid_status_event);
-
-        if (pid_status_event == 0)
-        {
-            DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got ZERO back from DNBProcessWaitForEvent....", __FUNCTION__, pid);
-        //    done = true;
-        }
-        else
-        {
-            if (pid_status_event & eEventStdioAvailable)
-            {
-                DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got stdio available event....", __FUNCTION__, pid);
-                ctx.Events().SetEvents (RNBContext::event_proc_stdio_available);
-                // Wait for the main thread to consume this notification if it requested we wait for it
-                ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
-            }
-
-            if (pid_status_event & eEventProfileDataAvailable)
-            {
-                DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got profile data event....", __FUNCTION__, pid);
-                ctx.Events().SetEvents (RNBContext::event_proc_profile_data);
-                // Wait for the main thread to consume this notification if it requested we wait for it
-                ctx.Events().WaitForResetAck(RNBContext::event_proc_profile_data);
-            }
-
-            if (pid_status_event & (eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged))
-            {
-                nub_state_t pid_state = DNBProcessGetState(pid);
-                DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got process state change: %s", __FUNCTION__, pid, DNBStateAsString(pid_state));
-
-                // Let the main thread know there is a process state change to see
-                ctx.Events().SetEvents (RNBContext::event_proc_state_changed);
-                // Wait for the main thread to consume this notification if it requested we wait for it
-                ctx.Events().WaitForResetAck(RNBContext::event_proc_state_changed);
-
-                switch (pid_state)
-                {
-                case eStateStopped:
-                    break;
-
-                case eStateInvalid:
-                case eStateExited:
-                case eStateDetached:
-                    done = true;
-                    break;
-                default:
-                    break;
-                }
-            }
-
-            // Reset any events that we consumed.
-            DNBProcessResetEvents(pid, pid_status_event);
-
-        }
-    }
-    DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (arg=%p, pid=%4.4x): thread exiting...", __FUNCTION__, arg, pid);
-    ctx.Events().ResetEvents(event_proc_thread_running);
-    ctx.Events().SetEvents(event_proc_thread_exiting);
+void *RNBContext::ThreadFunctionProcessStatus(void *arg) {
+  RNBRemoteSP remoteSP(g_remoteSP);
+  RNBRemote *remote = remoteSP.get();
+  if (remote == NULL)
     return NULL;
-}
+  RNBContext &ctx = remote->Context();
 
+  nub_process_t pid = ctx.ProcessID();
+  DNBLogThreadedIf(LOG_RNB_PROC,
+                   "RNBContext::%s (arg=%p, pid=%4.4x): thread starting...",
+                   __FUNCTION__, arg, pid);
+  ctx.Events().SetEvents(RNBContext::event_proc_thread_running);
 
-const char*
-RNBContext::EventsAsString (nub_event_t events, std::string& s)
-{
-    s.clear();
-    if (events & event_proc_state_changed)
-        s += "proc_state_changed ";
-    if (events & event_proc_thread_running)
-        s += "proc_thread_running ";
-    if (events & event_proc_thread_exiting)
-        s += "proc_thread_exiting ";
-    if (events & event_proc_stdio_available)
-        s += "proc_stdio_available ";
-    if (events & event_proc_profile_data)
-        s += "proc_profile_data ";
-    if (events & event_darwin_log_data_available)
-        s += "darwin_log_data_available ";
-    if (events & event_read_packet_available)
-        s += "read_packet_available ";
-    if (events & event_read_thread_running)
-        s += "read_thread_running ";
-    if (events & event_read_thread_running)
-        s += "read_thread_running ";
-    return s.c_str();
-}
+#if defined(__APPLE__)
+  pthread_setname_np("child process status watcher 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);
+  }
+#endif
+#endif
 
-const char *
-RNBContext::LaunchStatusAsString (std::string& s)
-{
-    s.clear();
+  bool done = false;
+  while (!done) {
+    DNBLogThreadedIf(LOG_RNB_PROC,
+                     "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
+                     "eEventProcessRunningStateChanged | "
+                     "eEventProcessStoppedStateChanged | eEventStdioAvailable "
+                     "| eEventProfileDataAvailable, true)...",
+                     __FUNCTION__);
+    nub_event_t pid_status_event = DNBProcessWaitForEvents(
+        pid,
+        eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged |
+            eEventStdioAvailable | eEventProfileDataAvailable,
+        true, NULL);
+    DNBLogThreadedIf(LOG_RNB_PROC,
+                     "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
+                     "eEventProcessRunningStateChanged | "
+                     "eEventProcessStoppedStateChanged | eEventStdioAvailable "
+                     "| eEventProfileDataAvailable, true) => 0x%8.8x",
+                     __FUNCTION__, pid_status_event);
 
-    const char *err_str = m_launch_status.AsString();
-    if (err_str)
-        s = err_str;
-    else
-    {
-        char error_num_str[64];
-        snprintf(error_num_str, sizeof(error_num_str), "%u", m_launch_status.Error());
-        s = error_num_str;
+    if (pid_status_event == 0) {
+      DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got ZERO back "
+                                     "from DNBProcessWaitForEvent....",
+                       __FUNCTION__, pid);
+      //    done = true;
+    } else {
+      if (pid_status_event & eEventStdioAvailable) {
+        DNBLogThreadedIf(
+            LOG_RNB_PROC,
+            "RNBContext::%s (pid=%4.4x) got stdio available event....",
+            __FUNCTION__, pid);
+        ctx.Events().SetEvents(RNBContext::event_proc_stdio_available);
+        // Wait for the main thread to consume this notification if it requested
+        // we wait for it
+        ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
+      }
+
+      if (pid_status_event & eEventProfileDataAvailable) {
+        DNBLogThreadedIf(
+            LOG_RNB_PROC,
+            "RNBContext::%s (pid=%4.4x) got profile data event....",
+            __FUNCTION__, pid);
+        ctx.Events().SetEvents(RNBContext::event_proc_profile_data);
+        // Wait for the main thread to consume this notification if it requested
+        // we wait for it
+        ctx.Events().WaitForResetAck(RNBContext::event_proc_profile_data);
+      }
+
+      if (pid_status_event & (eEventProcessRunningStateChanged |
+                              eEventProcessStoppedStateChanged)) {
+        nub_state_t pid_state = DNBProcessGetState(pid);
+        DNBLogThreadedIf(
+            LOG_RNB_PROC,
+            "RNBContext::%s (pid=%4.4x) got process state change: %s",
+            __FUNCTION__, pid, DNBStateAsString(pid_state));
+
+        // Let the main thread know there is a process state change to see
+        ctx.Events().SetEvents(RNBContext::event_proc_state_changed);
+        // Wait for the main thread to consume this notification if it requested
+        // we wait for it
+        ctx.Events().WaitForResetAck(RNBContext::event_proc_state_changed);
+
+        switch (pid_state) {
+        case eStateStopped:
+          break;
+
+        case eStateInvalid:
+        case eStateExited:
+        case eStateDetached:
+          done = true;
+          break;
+        default:
+          break;
+        }
+      }
+
+      // Reset any events that we consumed.
+      DNBProcessResetEvents(pid, pid_status_event);
     }
-    return s.c_str();
+  }
+  DNBLogThreadedIf(LOG_RNB_PROC,
+                   "RNBContext::%s (arg=%p, pid=%4.4x): thread exiting...",
+                   __FUNCTION__, arg, pid);
+  ctx.Events().ResetEvents(event_proc_thread_running);
+  ctx.Events().SetEvents(event_proc_thread_exiting);
+  return NULL;
 }
 
-bool
-RNBContext::ProcessStateRunning() const
-{
-    nub_state_t pid_state = DNBProcessGetState(m_pid);
-    return pid_state == eStateRunning || pid_state == eStateStepping;
+const char *RNBContext::EventsAsString(nub_event_t events, std::string &s) {
+  s.clear();
+  if (events & event_proc_state_changed)
+    s += "proc_state_changed ";
+  if (events & event_proc_thread_running)
+    s += "proc_thread_running ";
+  if (events & event_proc_thread_exiting)
+    s += "proc_thread_exiting ";
+  if (events & event_proc_stdio_available)
+    s += "proc_stdio_available ";
+  if (events & event_proc_profile_data)
+    s += "proc_profile_data ";
+  if (events & event_darwin_log_data_available)
+    s += "darwin_log_data_available ";
+  if (events & event_read_packet_available)
+    s += "read_packet_available ";
+  if (events & event_read_thread_running)
+    s += "read_thread_running ";
+  if (events & event_read_thread_running)
+    s += "read_thread_running ";
+  return s.c_str();
+}
+
+const char *RNBContext::LaunchStatusAsString(std::string &s) {
+  s.clear();
+
+  const char *err_str = m_launch_status.AsString();
+  if (err_str)
+    s = err_str;
+  else {
+    char error_num_str[64];
+    snprintf(error_num_str, sizeof(error_num_str), "%u",
+             m_launch_status.Error());
+    s = error_num_str;
+  }
+  return s.c_str();
+}
+
+bool RNBContext::ProcessStateRunning() const {
+  nub_state_t pid_state = DNBProcessGetState(m_pid);
+  return pid_state == eStateRunning || pid_state == eStateStepping;
 }
