[Lldb-commits] [lldb] d081077 - [lldb] Modernize ThreadLauncher

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 23 05:26:17 PST 2022


Author: Pavel Labath
Date: 2022-02-23T14:25:59+01:00
New Revision: d0810779b1f310d99176467d5d5b5aa4e26d7eb5

URL: https://github.com/llvm/llvm-project/commit/d0810779b1f310d99176467d5d5b5aa4e26d7eb5
DIFF: https://github.com/llvm/llvm-project/commit/d0810779b1f310d99176467d5d5b5aa4e26d7eb5.diff

LOG: [lldb] Modernize ThreadLauncher

Accept a function object instead of a raw pointer. This avoids a bunch
of boilerplate typically needed to pass arguments to the thread
functions.

Differential Revision: https://reviews.llvm.org/D120321

Added: 
    lldb/unittests/Host/ThreadLauncherTest.cpp

Modified: 
    lldb/include/lldb/Core/Communication.h
    lldb/include/lldb/Core/Debugger.h
    lldb/include/lldb/Host/ThreadLauncher.h
    lldb/include/lldb/Target/Process.h
    lldb/source/API/SBHostOS.cpp
    lldb/source/Core/Communication.cpp
    lldb/source/Core/Debugger.cpp
    lldb/source/Host/common/Host.cpp
    lldb/source/Host/common/HostNativeThreadBase.cpp
    lldb/source/Host/common/ThreadLauncher.cpp
    lldb/source/Host/macosx/objcxx/Host.mm
    lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
    lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
    lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
    lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/source/Target/Process.cpp
    lldb/unittests/Host/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Communication.h b/lldb/include/lldb/Core/Communication.h
index fdcb6c5fb9822..44b3a16a05269 100644
--- a/lldb/include/lldb/Core/Communication.h
+++ b/lldb/include/lldb/Core/Communication.h
@@ -277,7 +277,7 @@ class Communication : public Broadcaster {
   ///     \b True if the read thread is running, \b false otherwise.
   bool ReadThreadIsRunning();
 
-  /// The static read thread function. This function will call the "DoRead"
+  /// The read thread function. This function will call the "DoRead"
   /// function continuously and wait for data to become available. When data
   /// is received it will append the available data to the internal cache and
   /// broadcast a \b eBroadcastBitReadThreadGotBytes event.
@@ -289,7 +289,7 @@ class Communication : public Broadcaster {
   ///     \b NULL.
   ///
   /// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t);
-  static lldb::thread_result_t ReadThread(lldb::thread_arg_t comm_ptr);
+  lldb::thread_result_t ReadThread();
 
   void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
                                           void *callback_baton);

diff  --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index f9a1f1eea54f2..d4fae0c5d09cb 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -439,8 +439,6 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
 
   void StopEventHandlerThread();
 
-  static lldb::thread_result_t EventHandlerThread(lldb::thread_arg_t arg);
-
   void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
                      bool cancel_top_handler = true);
 
@@ -454,9 +452,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
 
   void JoinIOHandlerThread();
 
-  static lldb::thread_result_t IOHandlerThread(lldb::thread_arg_t arg);
+  lldb::thread_result_t IOHandlerThread();
 
-  void DefaultEventHandler();
+  lldb::thread_result_t DefaultEventHandler();
 
   void HandleBreakpointEvent(const lldb::EventSP &event_sp);
 

diff  --git a/lldb/include/lldb/Host/ThreadLauncher.h b/lldb/include/lldb/Host/ThreadLauncher.h
index 00b42fa6a11d5..8bb6c79466a76 100644
--- a/lldb/include/lldb/Host/ThreadLauncher.h
+++ b/lldb/include/lldb/Host/ThreadLauncher.h
@@ -20,8 +20,8 @@ namespace lldb_private {
 class ThreadLauncher {
 public:
   static llvm::Expected<HostThread>
-  LaunchThread(llvm::StringRef name, lldb::thread_func_t thread_function,
-               lldb::thread_arg_t thread_arg,
+  LaunchThread(llvm::StringRef name,
+               std::function<lldb::thread_result_t()> thread_function,
                size_t min_stack_byte_size = 0); // Minimum stack size in bytes,
                                                 // set stack size to zero for
                                                 // default platform thread stack
@@ -29,12 +29,11 @@ class ThreadLauncher {
 
   struct HostThreadCreateInfo {
     std::string thread_name;
-    lldb::thread_func_t thread_fptr;
-    lldb::thread_arg_t thread_arg;
+    std::function<lldb::thread_result_t()> impl;
 
-    HostThreadCreateInfo(const char *name, lldb::thread_func_t fptr,
-                         lldb::thread_arg_t arg)
-        : thread_name(name ? name : ""), thread_fptr(fptr), thread_arg(arg) {}
+    HostThreadCreateInfo(std::string thread_name,
+                         std::function<lldb::thread_result_t()> impl)
+        : thread_name(std::move(thread_name)), impl(std::move(impl)) {}
   };
 };
 }

diff  --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index adceec619ff04..23debbee705ea 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2989,17 +2989,6 @@ void PruneThreadPlans();
   void ResumePrivateStateThread();
 
 private:
-  struct PrivateStateThreadArgs {
-    PrivateStateThreadArgs(Process *p, bool s)
-        : process(p), is_secondary_thread(s){};
-    Process *process;
-    bool is_secondary_thread;
-  };
-
-  // arg is a pointer to a new'ed PrivateStateThreadArgs structure.
-  // PrivateStateThread will free it for you.
-  static lldb::thread_result_t PrivateStateThread(void *arg);
-
   // The starts up the private state thread that will watch for events from the
   // debugee. Pass true for is_secondary_thread in the case where you have to
   // temporarily spin up a secondary state thread to handle events from a hand-

diff  --git a/lldb/source/API/SBHostOS.cpp b/lldb/source/API/SBHostOS.cpp
index 06cf654031a1d..cb026fd9203b9 100644
--- a/lldb/source/API/SBHostOS.cpp
+++ b/lldb/source/API/SBHostOS.cpp
@@ -102,7 +102,9 @@ lldb::thread_t SBHostOS::ThreadCreate(const char *name,
                                       void *thread_arg, SBError *error_ptr) {
   LLDB_INSTRUMENT_VA(name, thread_function, thread_arg, error_ptr);
   llvm::Expected<HostThread> thread =
-      ThreadLauncher::LaunchThread(name, thread_function, thread_arg);
+      ThreadLauncher::LaunchThread(name, [thread_function, thread_arg] {
+        return thread_function(thread_arg);
+      });
   if (!thread) {
     if (error_ptr)
       error_ptr->SetError(Status(thread.takeError()));

diff  --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp
index 0e4d4fc49a429..f41ce46ede88f 100644
--- a/lldb/source/Core/Communication.cpp
+++ b/lldb/source/Core/Communication.cpp
@@ -213,7 +213,7 @@ bool Communication::StartReadThread(Status *error_ptr) {
   m_read_thread_enabled = true;
   m_read_thread_did_exit = false;
   auto maybe_thread = ThreadLauncher::LaunchThread(
-      thread_name, Communication::ReadThread, this);
+      thread_name, [this] { return ReadThread(); });
   if (maybe_thread) {
     m_read_thread = *maybe_thread;
   } else {
@@ -311,12 +311,10 @@ size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
 
 bool Communication::ReadThreadIsRunning() { return m_read_thread_enabled; }
 
-lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
-  Communication *comm = (Communication *)p;
-
+lldb::thread_result_t Communication::ReadThread() {
   Log *log = GetLog(LLDBLog::Communication);
 
-  LLDB_LOGF(log, "%p Communication::ReadThread () thread starting...", p);
+  LLDB_LOG(log, "Communication({0}) thread starting...", this);
 
   uint8_t buf[1024];
 
@@ -324,11 +322,11 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
   ConnectionStatus status = eConnectionStatusSuccess;
   bool done = false;
   bool disconnect = false;
-  while (!done && comm->m_read_thread_enabled) {
-    size_t bytes_read = comm->ReadFromConnection(
+  while (!done && m_read_thread_enabled) {
+    size_t bytes_read = ReadFromConnection(
         buf, sizeof(buf), std::chrono::seconds(5), status, &error);
     if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
-      comm->AppendBytesToCache(buf, bytes_read, true, status);
+      AppendBytesToCache(buf, bytes_read, true, status);
 
     switch (status) {
     case eConnectionStatusSuccess:
@@ -336,12 +334,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
 
     case eConnectionStatusEndOfFile:
       done = true;
-      disconnect = comm->GetCloseOnEOF();
+      disconnect = GetCloseOnEOF();
       break;
     case eConnectionStatusError: // Check GetError() for details
       if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
         // EIO on a pipe is usually caused by remote shutdown
-        disconnect = comm->GetCloseOnEOF();
+        disconnect = GetCloseOnEOF();
         done = true;
       }
       if (error.Fail())
@@ -352,7 +350,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
                                        // SynchronizeWithReadThread()
       // The connection returns eConnectionStatusInterrupted only when there is
       // no input pending to be read, so we can signal that.
-      comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+      BroadcastEvent(eBroadcastBitNoMorePendingInput);
       break;
     case eConnectionStatusNoConnection:   // No connection
     case eConnectionStatusLostConnection: // Lost connection while connected to
@@ -367,26 +365,25 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
     }
   }
   log = GetLog(LLDBLog::Communication);
-  if (log)
-    LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p);
+  LLDB_LOG(log, "Communication({0}) thread exiting...", this);
 
   // Handle threads wishing to synchronize with us.
   {
     // Prevent new ones from showing up.
-    comm->m_read_thread_did_exit = true;
+    m_read_thread_did_exit = true;
 
     // Unblock any existing thread waiting for the synchronization signal.
-    comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+    BroadcastEvent(eBroadcastBitNoMorePendingInput);
 
     // Wait for the thread to finish...
-    std::lock_guard<std::mutex> guard(comm->m_synchronize_mutex);
+    std::lock_guard<std::mutex> guard(m_synchronize_mutex);
     // ... and disconnect.
     if (disconnect)
-      comm->Disconnect();
+      Disconnect();
   }
 
   // Let clients know that this thread is exiting
-  comm->BroadcastEvent(eBroadcastBitReadThreadDidExit);
+  BroadcastEvent(eBroadcastBitReadThreadDidExit);
   return {};
 }
 

diff  --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index b4ef65c2a87f0..ae4fb93e6d4af 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1576,7 +1576,7 @@ void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
   m_forward_listener_sp.reset();
 }
 
-void Debugger::DefaultEventHandler() {
+lldb::thread_result_t Debugger::DefaultEventHandler() {
   ListenerSP listener_sp(GetListener());
   ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
   ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
@@ -1662,10 +1662,6 @@ void Debugger::DefaultEventHandler() {
       }
     }
   }
-}
-
-lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
-  ((Debugger *)arg)->DefaultEventHandler();
   return {};
 }
 
@@ -1687,8 +1683,9 @@ bool Debugger::StartEventHandlerThread() {
 
     // Use larger 8MB stack for this thread
     llvm::Expected<HostThread> event_handler_thread =
-        ThreadLauncher::LaunchThread(thread_name, EventHandlerThread, this,
-                                     g_debugger_event_thread_stack_bytes);
+        ThreadLauncher::LaunchThread(
+            thread_name, [this] { return DefaultEventHandler(); },
+            g_debugger_event_thread_stack_bytes);
 
     if (event_handler_thread) {
       m_event_handler_thread = *event_handler_thread;
@@ -1716,10 +1713,9 @@ void Debugger::StopEventHandlerThread() {
   }
 }
 
-lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
-  Debugger *debugger = (Debugger *)arg;
-  debugger->RunIOHandlers();
-  debugger->StopEventHandlerThread();
+lldb::thread_result_t Debugger::IOHandlerThread() {
+  RunIOHandlers();
+  StopEventHandlerThread();
   return {};
 }
 
@@ -1728,7 +1724,7 @@ bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
 bool Debugger::StartIOHandlerThread() {
   if (!m_io_handler_thread.IsJoinable()) {
     llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
-        "lldb.debugger.io-handler", IOHandlerThread, this,
+        "lldb.debugger.io-handler", [this] { return IOHandlerThread(); },
         8 * 1024 * 1024); // Use larger 8MB stack for this thread
     if (io_handler_thread) {
       m_io_handler_thread = *io_handler_thread;

diff  --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index f6cb82408e3c5..8bfc54aa387ee 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -92,29 +92,22 @@ using namespace lldb;
 using namespace lldb_private;
 
 #if !defined(__APPLE__) && !defined(_WIN32)
-struct MonitorInfo {
-  lldb::pid_t pid; // The process ID to monitor
-  Host::MonitorChildProcessCallback
-      callback; // The callback function to call when "pid" exits or signals
-  bool monitor_signals; // If true, call the callback when "pid" gets signaled.
-};
-
-static thread_result_t MonitorChildProcessThreadFunction(void *arg);
+static thread_result_t
+MonitorChildProcessThreadFunction(::pid_t pid,
+                                  Host::MonitorChildProcessCallback callback,
+                                  bool monitor_signals);
 
 llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
     const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
     bool monitor_signals) {
-  MonitorInfo *info_ptr = new MonitorInfo();
-
-  info_ptr->pid = pid;
-  info_ptr->callback = callback;
-  info_ptr->monitor_signals = monitor_signals;
-
   char thread_name[256];
   ::snprintf(thread_name, sizeof(thread_name),
              "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
-  return ThreadLauncher::LaunchThread(
-      thread_name, MonitorChildProcessThreadFunction, info_ptr, 0);
+  assert(pid <= UINT32_MAX);
+  return ThreadLauncher::LaunchThread(thread_name, [pid, callback,
+                                                    monitor_signals] {
+    return MonitorChildProcessThreadFunction(pid, callback, monitor_signals);
+  });
 }
 
 #ifndef __linux__
@@ -163,20 +156,14 @@ static bool CheckForMonitorCancellation() {
   return false;
 }
 
-static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
+static thread_result_t
+MonitorChildProcessThreadFunction(::pid_t pid,
+                                  Host::MonitorChildProcessCallback callback,
+                                  bool monitor_signals) {
   Log *log = GetLog(LLDBLog::Process);
-  const char *function = __FUNCTION__;
-  LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg);
-
-  MonitorInfo *info = (MonitorInfo *)arg;
+  LLDB_LOG(log, "pid = {0}, monitor_signals = {1}", pid, monitor_signals);
 
-  const Host::MonitorChildProcessCallback callback = info->callback;
-  const bool monitor_signals = info->monitor_signals;
-
-  assert(info->pid <= UINT32_MAX);
-  const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
-
-  delete info;
+  pid = monitor_signals ? -1 * getpgid(pid) : pid;
 
   int status = -1;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
@@ -194,8 +181,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
 
   while (true) {
     log = GetLog(LLDBLog::Process);
-    LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...",
-              function, pid, options);
+    LLDB_LOG(log, "::waitpid({0}, &status, {1})...", pid, options);
 
     if (CheckForMonitorCancellation())
       break;
@@ -211,8 +197,8 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
         continue;
       else {
         LLDB_LOG(log,
-                 "arg = {0}, thread exiting because waitpid failed ({1})...",
-                 arg, llvm::sys::StrError());
+                 "pid = {0}, thread exiting because waitpid failed ({1})...",
+                 pid, llvm::sys::StrError());
         break;
       }
     } else if (wait_pid > 0) {
@@ -245,12 +231,11 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
 #endif
 
         log = GetLog(LLDBLog::Process);
-        LLDB_LOGF(log,
-                  "%s ::waitpid (pid = %" PRIi32
-                  ", &status, options = %i) => pid = %" PRIi32
-                  ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
-                  function, pid, options, wait_pid, status, status_cstr, signal,
-                  exit_status);
+        LLDB_LOG(log,
+                 "::waitpid({0}, &status, {1}) => pid = {2}, status = {3:x} "
+                 "({4}), signal = {5}, exit_state = {6}",
+                 pid, options, wait_pid, status, status_cstr, signal,
+                 exit_status);
 
         if (exited || (signal != 0 && monitor_signals)) {
           bool callback_return = false;
@@ -259,18 +244,18 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
 
           // If our process exited, then this thread should exit
           if (exited && wait_pid == abs(pid)) {
-            LLDB_LOGF(log,
-                      "%s (arg = %p) thread exiting because pid received "
-                      "exit signal...",
-                      __FUNCTION__, arg);
+            LLDB_LOG(
+                log,
+                "pid = {0} thread exiting because pid received exit signal...",
+                pid);
             break;
           }
           // If the callback returns true, it means this process should exit
           if (callback_return) {
-            LLDB_LOGF(log,
-                      "%s (arg = %p) thread exiting because callback "
-                      "returned true...",
-                      __FUNCTION__, arg);
+            LLDB_LOG(
+                log,
+                "pid = {0} thread exiting because callback returned true...",
+                pid);
             break;
           }
         }
@@ -278,9 +263,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
     }
   }
 
-  log = GetLog(LLDBLog::Process);
-  LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg);
-
+  LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid);
   return nullptr;
 }
 

diff  --git a/lldb/source/Host/common/HostNativeThreadBase.cpp b/lldb/source/Host/common/HostNativeThreadBase.cpp
index 4e69306e4d659..5814a7fd54bb5 100644
--- a/lldb/source/Host/common/HostNativeThreadBase.cpp
+++ b/lldb/source/Host/common/HostNativeThreadBase.cpp
@@ -52,16 +52,12 @@ lldb::thread_t HostNativeThreadBase::Release() {
 
 lldb::thread_result_t
 HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) {
-  ThreadLauncher::HostThreadCreateInfo *info =
-      (ThreadLauncher::HostThreadCreateInfo *)arg;
-  llvm::set_thread_name(info->thread_name);
-
-  thread_func_t thread_fptr = info->thread_fptr;
-  thread_arg_t thread_arg = info->thread_arg;
+  std::unique_ptr<ThreadLauncher::HostThreadCreateInfo> info_up(
+      (ThreadLauncher::HostThreadCreateInfo *)arg);
+  llvm::set_thread_name(info_up->thread_name);
 
   Log *log = GetLog(LLDBLog::Thread);
   LLDB_LOGF(log, "thread created");
 
-  delete info;
-  return thread_fptr(thread_arg);
+  return info_up->impl();
 }

diff  --git a/lldb/source/Host/common/ThreadLauncher.cpp b/lldb/source/Host/common/ThreadLauncher.cpp
index bd104b3e4aed2..28c90215f8747 100644
--- a/lldb/source/Host/common/ThreadLauncher.cpp
+++ b/lldb/source/Host/common/ThreadLauncher.cpp
@@ -21,17 +21,18 @@
 using namespace lldb;
 using namespace lldb_private;
 
-llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
-    llvm::StringRef name, lldb::thread_func_t thread_function,
-    lldb::thread_arg_t thread_arg, size_t min_stack_byte_size) {
-  // Host::ThreadCreateTrampoline will delete this pointer for us.
-  HostThreadCreateInfo *info_ptr =
-      new HostThreadCreateInfo(name.data(), thread_function, thread_arg);
+llvm::Expected<HostThread>
+ThreadLauncher::LaunchThread(llvm::StringRef name,
+                             std::function<thread_result_t()> impl,
+                             size_t min_stack_byte_size) {
+  // Host::ThreadCreateTrampoline will take ownership if thread creation is
+  // successful.
+  auto info_up = std::make_unique<HostThreadCreateInfo>(name.str(), impl);
   lldb::thread_t thread;
 #ifdef _WIN32
   thread = (lldb::thread_t)::_beginthreadex(
       0, (unsigned)min_stack_byte_size,
-      HostNativeThread::ThreadCreateTrampoline, info_ptr, 0, NULL);
+      HostNativeThread::ThreadCreateTrampoline, info_up.get(), 0, NULL);
   if (thread == LLDB_INVALID_HOST_THREAD)
     return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError()));
 #else
@@ -63,7 +64,7 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
   }
   int err =
       ::pthread_create(&thread, thread_attr_ptr,
-                       HostNativeThread::ThreadCreateTrampoline, info_ptr);
+                       HostNativeThread::ThreadCreateTrampoline, info_up.get());
 
   if (destroy_attr)
     ::pthread_attr_destroy(&thread_attr);
@@ -73,5 +74,6 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
         std::error_code(err, std::generic_category()));
 #endif
 
+  info_up.release();
   return HostThread(thread);
 }

diff  --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm
index 969173e7122cd..ab2c295004e4c 100644
--- a/lldb/source/Host/macosx/objcxx/Host.mm
+++ b/lldb/source/Host/macosx/objcxx/Host.mm
@@ -136,8 +136,7 @@
 
 #if TARGET_OS_OSX
 
-static void *AcceptPIDFromInferior(void *arg) {
-  const char *connect_url = (const char *)arg;
+static void *AcceptPIDFromInferior(const char *connect_url) {
   ConnectionFileDescriptor file_conn;
   Status error;
   if (file_conn.Connect(connect_url, &error) == eConnectionStatusSuccess) {
@@ -286,7 +285,7 @@ repeat with the_window in (get windows)\n\
   // to the process that we wanted to launch. So when our process actually
   // gets launched, we will handshake with it and get the process ID for it.
   llvm::Expected<HostThread> accept_thread = ThreadLauncher::LaunchThread(
-      unix_socket_name, AcceptPIDFromInferior, connect_url);
+      unix_socket_name, [&] { return AcceptPIDFromInferior(connect_url); });
 
   if (!accept_thread)
     return Status(accept_thread.takeError());

diff  --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 65112275892a3..8843dc87e5cbf 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -724,7 +724,7 @@ bool ProcessKDP::StartAsyncThread() {
     return true;
 
   llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
-      "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this);
+      "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
   if (!async_thread) {
     LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
                    "failed to launch host thread: {}");
@@ -746,25 +746,21 @@ void ProcessKDP::StopAsyncThread() {
     m_async_thread.Join(nullptr);
 }
 
-void *ProcessKDP::AsyncThread(void *arg) {
-  ProcessKDP *process = (ProcessKDP *)arg;
-
-  const lldb::pid_t pid = process->GetID();
+void *ProcessKDP::AsyncThread() {
+  const lldb::pid_t pid = GetID();
 
   Log *log = GetLog(KDPLog::Process);
   LLDB_LOGF(log,
-            "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
-            ") thread starting...",
-            arg, pid);
+            "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",
+            pid);
 
   ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
   EventSP event_sp;
   const uint32_t desired_event_mask =
       eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
 
-  if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
-                                           desired_event_mask) ==
-      desired_event_mask) {
+  if (listener_sp->StartListeningForEvents(
+          &m_async_broadcaster, desired_event_mask) == desired_event_mask) {
     bool done = false;
     while (!done) {
       LLDB_LOGF(log,
@@ -787,9 +783,9 @@ void *ProcessKDP::AsyncThread(void *arg) {
           switch (event_type) {
           case eBroadcastBitAsyncContinue: {
             is_running = true;
-            if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
+            if (m_comm.WaitForPacketWithTimeoutMicroSeconds(
                     exc_reply_packet, 1 * USEC_PER_SEC)) {
-              ThreadSP thread_sp(process->GetKernelThread());
+              ThreadSP thread_sp(GetKernelThread());
               if (thread_sp) {
                 lldb::RegisterContextSP reg_ctx_sp(
                     thread_sp->GetRegisterContext());
@@ -801,7 +797,7 @@ void *ProcessKDP::AsyncThread(void *arg) {
 
               // TODO: parse the stop reply packet
               is_running = false;
-              process->SetPrivateState(eStateStopped);
+              SetPrivateState(eStateStopped);
             } else {
               // Check to see if we are supposed to exit. There is no way to
               // interrupt a running kernel, so all we can do is wait for an
@@ -843,12 +839,10 @@ void *ProcessKDP::AsyncThread(void *arg) {
     }
   }
 
-  LLDB_LOGF(log,
-            "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
-            ") thread exiting...",
-            arg, pid);
+  LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",
+            pid);
 
-  process->m_async_thread.Reset();
+  m_async_thread.Reset();
   return NULL;
 }
 

diff  --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 3386354d0b4cb..a8cfb0ec9f870 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -179,7 +179,7 @@ class ProcessKDP : public lldb_private::Process {
 
   void StopAsyncThread();
 
-  static void *AsyncThread(void *arg);
+  void *AsyncThread();
 
 private:
   // For ProcessKDP only

diff  --git a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
index a78ca2aabe134..e442650f0920e 100644
--- a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -36,25 +36,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-namespace {
-struct DebugLaunchContext {
-  DebugLaunchContext(DebuggerThread *thread,
-                     const ProcessLaunchInfo &launch_info)
-      : m_thread(thread), m_launch_info(launch_info) {}
-  DebuggerThread *m_thread;
-  ProcessLaunchInfo m_launch_info;
-};
-
-struct DebugAttachContext {
-  DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
-                     const ProcessAttachInfo &attach_info)
-      : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
-  DebuggerThread *m_thread;
-  lldb::pid_t m_pid;
-  ProcessAttachInfo m_attach_info;
-};
-} // namespace
-
 DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
     : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
       m_is_shutting_down(false) {
@@ -68,11 +49,9 @@ Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
   LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
 
   Status result;
-  DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
-
-  llvm::Expected<HostThread> secondary_thread =
-      ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
-                                   DebuggerThreadLaunchRoutine, context);
+  llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
+      "lldb.plugin.process-windows.secondary[?]",
+      [this, launch_info] { return DebuggerThreadLaunchRoutine(launch_info); });
   if (!secondary_thread) {
     result = Status(secondary_thread.takeError());
     LLDB_LOG(log, "couldn't launch debugger thread. {0}", result);
@@ -87,11 +66,10 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid,
   LLDB_LOG(log, "attaching to '{0}'", pid);
 
   Status result;
-  DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
-
-  llvm::Expected<HostThread> secondary_thread =
-      ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
-                                   DebuggerThreadAttachRoutine, context);
+  llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
+      "lldb.plugin.process-windows.secondary[?]", [this, pid, attach_info] {
+        return DebuggerThreadAttachRoutine(pid, attach_info);
+      });
   if (!secondary_thread) {
     result = Status(secondary_thread.takeError());
     LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result);
@@ -100,22 +78,6 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid,
   return result;
 }
 
-lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
-  DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
-  lldb::thread_result_t result =
-      context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
-  delete context;
-  return result;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
-  DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
-  lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
-      context->m_pid, context->m_attach_info);
-  delete context;
-  return result;
-}
-
 lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
     const ProcessLaunchInfo &launch_info) {
   // Grab a shared_ptr reference to this so that we know it won't get deleted

diff  --git a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
index 56701307fd757..e3439ff34584b 100644
--- a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
+++ b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
@@ -91,10 +91,8 @@ class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
   // exit.
   bool m_detached = false;
 
-  static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
   lldb::thread_result_t
   DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
-  static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
   lldb::thread_result_t
   DebuggerThreadAttachRoutine(lldb::pid_t pid,
                               const ProcessAttachInfo &launch_info);

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 38d9e400978d2..d660a4d070421 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -843,7 +843,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname,
   m_listen_url = listen_url;
   SetConnection(std::make_unique<ConnectionFileDescriptor>());
   llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
-      listen_url, GDBRemoteCommunication::ListenThread, this);
+      listen_url, [this] { return GDBRemoteCommunication::ListenThread(); });
   if (!listen_thread)
     return Status(listen_thread.takeError());
   m_listen_thread = *listen_thread;
@@ -857,23 +857,22 @@ bool GDBRemoteCommunication::JoinListenThread() {
   return true;
 }
 
-lldb::thread_result_t
-GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
-  GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+lldb::thread_result_t GDBRemoteCommunication::ListenThread() {
   Status error;
   ConnectionFileDescriptor *connection =
-      (ConnectionFileDescriptor *)comm->GetConnection();
+      (ConnectionFileDescriptor *)GetConnection();
 
   if (connection) {
     // Do the listen on another thread so we can continue on...
     if (connection->Connect(
-            comm->m_listen_url.c_str(), [comm](llvm::StringRef port_str) {
+            m_listen_url.c_str(),
+            [this](llvm::StringRef port_str) {
               uint16_t port = 0;
               llvm::to_integer(port_str, port, 10);
-              comm->m_port_promise.set_value(port);
+              m_port_promise.set_value(port);
             },
             &error) != eConnectionStatusSuccess)
-      comm->SetConnection(nullptr);
+      SetConnection(nullptr);
   }
   return {};
 }

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index afc7e740d4c96..a325baa59ba3e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -218,7 +218,7 @@ class GDBRemoteCommunication : public Communication {
 
   bool JoinListenThread();
 
-  static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+  lldb::thread_result_t ListenThread();
 
 private:
   // Promise used to grab the port number from listening thread

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index c40e738cae515..3f5cb1606f21b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3541,8 +3541,10 @@ bool ProcessGDBRemote::StartAsyncThread() {
     // Create a thread that watches our internal state and controls which
     // events make it to clients (into the DCProcess event queue).
 
-    llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
-        "<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this);
+    llvm::Expected<HostThread> async_thread =
+        ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", [this] {
+          return ProcessGDBRemote::AsyncThread();
+        });
     if (!async_thread) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
                      "failed to launch host thread: {}");
@@ -3580,14 +3582,10 @@ void ProcessGDBRemote::StopAsyncThread() {
         __FUNCTION__);
 }
 
-thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
-  ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
-
+thread_result_t ProcessGDBRemote::AsyncThread() {
   Log *log = GetLog(GDBRLog::Process);
-  LLDB_LOGF(log,
-            "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
-            ") thread starting...",
-            __FUNCTION__, arg, process->GetID());
+  LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread starting...",
+            __FUNCTION__, GetID());
 
   EventSP event_sp;
 
@@ -3603,19 +3601,19 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
   // fetch loop.
 
   bool done = false;
-  while (!done && process->GetPrivateState() != eStateExited) {
+  while (!done && GetPrivateState() != eStateExited) {
     LLDB_LOGF(log,
-              "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+              "ProcessGDBRemote::%s(pid = %" PRIu64
               ") listener.WaitForEvent (NULL, event_sp)...",
-              __FUNCTION__, arg, process->GetID());
+              __FUNCTION__, GetID());
 
-    if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+    if (m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
       const uint32_t event_type = event_sp->GetType();
-      if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
+      if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
         LLDB_LOGF(log,
-                  "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                  "ProcessGDBRemote::%s(pid = %" PRIu64
                   ") Got an event of type: %d...",
-                  __FUNCTION__, arg, process->GetID(), event_type);
+                  __FUNCTION__, GetID(), event_type);
 
         switch (event_type) {
         case eBroadcastBitAsyncContinue: {
@@ -3627,39 +3625,39 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
                 (const char *)continue_packet->GetBytes();
             const size_t continue_cstr_len = continue_packet->GetByteSize();
             LLDB_LOGF(log,
-                      "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                      "ProcessGDBRemote::%s(pid = %" PRIu64
                       ") got eBroadcastBitAsyncContinue: %s",
-                      __FUNCTION__, arg, process->GetID(), continue_cstr);
+                      __FUNCTION__, GetID(), continue_cstr);
 
             if (::strstr(continue_cstr, "vAttach") == nullptr)
-              process->SetPrivateState(eStateRunning);
+              SetPrivateState(eStateRunning);
             StringExtractorGDBRemote response;
 
             StateType stop_state =
-                process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
-                    *process, *process->GetUnixSignals(),
+                GetGDBRemote().SendContinuePacketAndWaitForResponse(
+                    *this, *GetUnixSignals(),
                     llvm::StringRef(continue_cstr, continue_cstr_len),
-                    process->GetInterruptTimeout(), response);
+                    GetInterruptTimeout(), response);
 
             // We need to immediately clear the thread ID list so we are sure
             // to get a valid list of threads. The thread ID list might be
             // contained within the "response", or the stop reply packet that
             // caused the stop. So clear it now before we give the stop reply
             // packet to the process using the
-            // process->SetLastStopPacket()...
-            process->ClearThreadIDList();
+            // SetLastStopPacket()...
+            ClearThreadIDList();
 
             switch (stop_state) {
             case eStateStopped:
             case eStateCrashed:
             case eStateSuspended:
-              process->SetLastStopPacket(response);
-              process->SetPrivateState(stop_state);
+              SetLastStopPacket(response);
+              SetPrivateState(stop_state);
               break;
 
             case eStateExited: {
-              process->SetLastStopPacket(response);
-              process->ClearThreadIDList();
+              SetLastStopPacket(response);
+              ClearThreadIDList();
               response.SetFilePos(1);
 
               int exit_status = response.GetHexU8();
@@ -3674,7 +3672,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
                   extractor.GetHexByteString(desc_string);
                 }
               }
-              process->SetExitStatus(exit_status, desc_string.c_str());
+              SetExitStatus(exit_status, desc_string.c_str());
               done = true;
               break;
             }
@@ -3685,20 +3683,20 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
               // helpful error message about why the attach failed.
               if (::strstr(continue_cstr, "vAttach") != nullptr &&
                   response.GetError() == 0x87) {
-                process->SetExitStatus(-1, "cannot attach to process due to "
-                                           "System Integrity Protection");
+                SetExitStatus(-1, "cannot attach to process due to "
+                                  "System Integrity Protection");
               } else if (::strstr(continue_cstr, "vAttach") != nullptr &&
                          response.GetStatus().Fail()) {
-                process->SetExitStatus(-1, response.GetStatus().AsCString());
+                SetExitStatus(-1, response.GetStatus().AsCString());
               } else {
-                process->SetExitStatus(-1, "lost connection");
+                SetExitStatus(-1, "lost connection");
               }
               done = true;
               break;
             }
 
             default:
-              process->SetPrivateState(stop_state);
+              SetPrivateState(stop_state);
               break;
             }   // switch(stop_state)
           }     // if (continue_packet)
@@ -3707,49 +3705,47 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
 
         case eBroadcastBitAsyncThreadShouldExit:
           LLDB_LOGF(log,
-                    "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                    "ProcessGDBRemote::%s(pid = %" PRIu64
                     ") got eBroadcastBitAsyncThreadShouldExit...",
-                    __FUNCTION__, arg, process->GetID());
+                    __FUNCTION__, GetID());
           done = true;
           break;
 
         default:
           LLDB_LOGF(log,
-                    "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                    "ProcessGDBRemote::%s(pid = %" PRIu64
                     ") got unknown event 0x%8.8x",
-                    __FUNCTION__, arg, process->GetID(), event_type);
+                    __FUNCTION__, GetID(), event_type);
           done = true;
           break;
         }
-      } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+      } else if (event_sp->BroadcasterIs(&m_gdb_comm)) {
         switch (event_type) {
         case Communication::eBroadcastBitReadThreadDidExit:
-          process->SetExitStatus(-1, "lost connection");
+          SetExitStatus(-1, "lost connection");
           done = true;
           break;
 
         default:
           LLDB_LOGF(log,
-                    "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                    "ProcessGDBRemote::%s(pid = %" PRIu64
                     ") got unknown event 0x%8.8x",
-                    __FUNCTION__, arg, process->GetID(), event_type);
+                    __FUNCTION__, GetID(), event_type);
           done = true;
           break;
         }
       }
     } else {
       LLDB_LOGF(log,
-                "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                "ProcessGDBRemote::%s(pid = %" PRIu64
                 ") listener.WaitForEvent (NULL, event_sp) => false",
-                __FUNCTION__, arg, process->GetID());
+                __FUNCTION__, GetID());
       done = true;
     }
   }
 
-  LLDB_LOGF(log,
-            "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
-            ") thread exiting...",
-            __FUNCTION__, arg, process->GetID());
+  LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread exiting...",
+            __FUNCTION__, GetID());
 
   return {};
 }

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index dd907042608da..47b329eba731c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -342,7 +342,7 @@ class ProcessGDBRemote : public Process,
 
   void StopAsyncThread();
 
-  static lldb::thread_result_t AsyncThread(void *arg);
+  lldb::thread_result_t AsyncThread();
 
   static bool
   MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,

diff  --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index c70bfcfc448de..cbb10a0ac8506 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3509,12 +3509,13 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
                "<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID());
   }
 
-  // Create the private state thread, and start it running.
-  PrivateStateThreadArgs *args_ptr =
-      new PrivateStateThreadArgs(this, is_secondary_thread);
   llvm::Expected<HostThread> private_state_thread =
-      ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread,
-                                   (void *)args_ptr, 8 * 1024 * 1024);
+      ThreadLauncher::LaunchThread(
+          thread_name,
+          [this, is_secondary_thread] {
+            return RunPrivateStateThread(is_secondary_thread);
+          },
+          8 * 1024 * 1024);
   if (!private_state_thread) {
     LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}",
              llvm::toString(private_state_thread.takeError()));
@@ -3729,14 +3730,6 @@ Status Process::HaltPrivate() {
   return error;
 }
 
-thread_result_t Process::PrivateStateThread(void *arg) {
-  std::unique_ptr<PrivateStateThreadArgs> args_up(
-      static_cast<PrivateStateThreadArgs *>(arg));
-  thread_result_t result =
-      args_up->process->RunPrivateStateThread(args_up->is_secondary_thread);
-  return result;
-}
-
 thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
   bool control_only = true;
 

diff  --git a/lldb/unittests/Host/CMakeLists.txt b/lldb/unittests/Host/CMakeLists.txt
index ae6afd592e547..bf14bf16e4e36 100644
--- a/lldb/unittests/Host/CMakeLists.txt
+++ b/lldb/unittests/Host/CMakeLists.txt
@@ -12,6 +12,7 @@ set (FILES
   SocketAddressTest.cpp
   SocketTest.cpp
   SocketTestUtilities.cpp
+  ThreadLauncherTest.cpp
   XMLTest.cpp
 )
 

diff  --git a/lldb/unittests/Host/ThreadLauncherTest.cpp b/lldb/unittests/Host/ThreadLauncherTest.cpp
new file mode 100644
index 0000000000000..a19351a59b8dd
--- /dev/null
+++ b/lldb/unittests/Host/ThreadLauncherTest.cpp
@@ -0,0 +1,29 @@
+//===-- ThreadLauncherTest.cpp --------------------------------------------===//
+//
+// 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 "lldb/Host/ThreadLauncher.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+#include <future>
+
+using namespace lldb_private;
+
+TEST(ThreadLauncherTest, LaunchThread) {
+  std::promise<int> promise;
+  std::future<int> future = promise.get_future();
+  llvm::Expected<HostThread> thread =
+      ThreadLauncher::LaunchThread("test", [&promise] {
+        promise.set_value(47);
+        return (lldb::thread_result_t)47;
+      });
+  ASSERT_THAT_EXPECTED(thread, llvm::Succeeded());
+  EXPECT_EQ(future.get(), 47);
+  lldb::thread_result_t result;
+  thread->Join(&result);
+  EXPECT_EQ(result, (lldb::thread_result_t)47);
+}


        


More information about the lldb-commits mailing list