https://github.com/daniilavdeev updated 
https://github.com/llvm/llvm-project/pull/177572

>From 30083076f463633c4fb9665dec383b44dc3015b6 Mon Sep 17 00:00:00 2001
From: Daniil Avdeev <[email protected]>
Date: Mon, 26 Jan 2026 16:10:51 +0000
Subject: [PATCH] [lldb] address memory leakage in lldb-server

lldb-server has exhibited fairly unexpected behaviour. The time each
iteration of the main loop takes (attach + spawn a child process) has
been progressively increasing over the course of the lldb-server
execution. For instance, at the beginning of the remote tests run (when
a single instance of lldb-server on the remote side processes all the
incoming connections), each iteration took approximately 0.1 seconds,
increasing to 1.5 seconds by the end.

The analysis of the lldb-server application indicates that the
__libc_fork function takes more and more time on each iteration. The
most plausible interpretation of this fact would appear to be that the
application accumulates a certain resource that the fork function
subsequently had to process.

The following investigation has shown that the memory leakage did seem
to take place during the lldb-server execution. After the spawn of a
child process lldb-server additionally creates a monitoring thread, the
only purpose of which is to call a waitpid on the corresponding child
process. However, it appears to me that lldb-server application tracks
neither its children nor these internal threads, which ultimately
results in the threads not being joined or detached and the resources
associated with these threads won't be released.

Meanwhile, the creation of the thread is followed by the allocation of
the stack memory for this thread (usually 8MB), which is never released.
Given this behaviour, the amount of unfreed memory accumulated by the
lldb-server reaches approximately 30-35GB by the end of the test run. At
the same time, the fork function maps the parent's memory to the child
process, therefore the uncontrolled growth of unnecessary memory slows
the execution of the fork function significantly.

To summarise, the memory leakage that was caused by the inappropriate
managing of the internal threads appears to be the underlying cause of
the progressively increasing duration of the main loop, leading to
performance degradation of lldb-server application, which is especially
noticeable during long tests runs.

The proposed solution at this stage is to simply detach internal
threads, so that the OS can release memory associated with these
threads. That is to say, it seems to me that lldb-server doesn't have
appropriate mechanisms to track spawned threads, therefore a more
thoughtful approach would likely require changes to a substantial part
of the existing logic.
---
 lldb/source/Host/posix/HostProcessPosix.cpp     | 13 ++++++++++---
 lldb/source/Host/windows/HostProcessWindows.cpp |  8 +++++++-
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Host/posix/HostProcessPosix.cpp 
b/lldb/source/Host/posix/HostProcessPosix.cpp
index 2a118f0de9511..977ff70991bb6 100644
--- a/lldb/source/Host/posix/HostProcessPosix.cpp
+++ b/lldb/source/Host/posix/HostProcessPosix.cpp
@@ -6,9 +6,10 @@
 //
 
//===----------------------------------------------------------------------===//
 
-#include "lldb/Host/Host.h"
-#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/posix/HostProcessPosix.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/posix/HostThreadPosix.h"
 
 #include "llvm/ADT/STLExtras.h"
 
@@ -61,5 +62,11 @@ bool HostProcessPosix::IsRunning() const {
 
 llvm::Expected<HostThread> HostProcessPosix::StartMonitoring(
     const Host::MonitorChildProcessCallback &callback) {
-  return Host::StartMonitoringChildProcess(callback, m_process);
+  auto host_thread = Host::StartMonitoringChildProcess(callback, m_process);
+  if (!host_thread)
+    return host_thread;
+
+  auto &native_thread = host_thread->GetNativeThread();
+  native_thread.Detach();
+  return host_thread;
 }
diff --git a/lldb/source/Host/windows/HostProcessWindows.cpp 
b/lldb/source/Host/windows/HostProcessWindows.cpp
index 44cb333808773..8c7c57dd88462 100644
--- a/lldb/source/Host/windows/HostProcessWindows.cpp
+++ b/lldb/source/Host/windows/HostProcessWindows.cpp
@@ -84,10 +84,16 @@ llvm::Expected<HostThread> 
HostProcessWindows::StartMonitoring(
   // can have ownership over its own copy of the handle.
   if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
                         &process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
-    return ThreadLauncher::LaunchThread(
+    auto host_thread = ThreadLauncher::LaunchThread(
         "ChildProcessMonitor", [callback, process_handle] {
           return MonitorThread(callback, process_handle);
         });
+    if (!host_thread)
+      return host_thread;
+
+    auto &native_thread = host_thread->GetNativeThread();
+    native_thread.Reset();
+    return host_thread;
   } else {
     return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError()));
   }

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to