https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/129332
>From c63350db79ac6bcc6f180cc84a37e829d1c8b2a8 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Fri, 28 Feb 2025 14:54:42 -0600 Subject: [PATCH 1/6] [lldb-dap] Implement a MemoryMonitor for macOS & Linux This implements a memory monitor for macOS & Linux, and registers a callback that invokes SBDebugger::MemoryPressureDetected() when a low memory event is detected. --- lldb/tools/lldb-dap/CMakeLists.txt | 1 + lldb/tools/lldb-dap/MemoryMonitor.cpp | 114 ++++++++++++++++++++++++++ lldb/tools/lldb-dap/MemoryMonitor.h | 41 +++++++++ lldb/tools/lldb-dap/lldb-dap.cpp | 17 +++- 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 lldb/tools/lldb-dap/MemoryMonitor.cpp create mode 100644 lldb/tools/lldb-dap/MemoryMonitor.h diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 8b3c520ec4360..8db377e31c3c6 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -36,6 +36,7 @@ add_lldb_tool(lldb-dap RunInTerminal.cpp SourceBreakpoint.cpp Watchpoint.cpp + MemoryMonitor.cpp Handler/ResponseHandler.cpp Handler/AttachRequestHandler.cpp diff --git a/lldb/tools/lldb-dap/MemoryMonitor.cpp b/lldb/tools/lldb-dap/MemoryMonitor.cpp new file mode 100644 index 0000000000000..da3da42fe9b0f --- /dev/null +++ b/lldb/tools/lldb-dap/MemoryMonitor.cpp @@ -0,0 +1,114 @@ +//===-- MemoryMonitor.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 "MemoryMonitor.h" +#include "llvm/ADT/ScopeExit.h" +#include <atomic> +#include <cstdio> +#include <cstring> +#include <thread> + +#if defined(__APPLE__) +#include <dispatch/dispatch.h> +#endif + +#if defined(__linux__) +#include <fcntl.h> +#include <poll.h> +#include <unistd.h> +#endif + +using namespace lldb_dap; + +#if defined(__APPLE__) +class MemoryMonitorDarwin : public MemoryMonitor { + using MemoryMonitor::MemoryMonitor; + void Start() override { + m_memory_pressure_source = dispatch_source_create( + DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, + 0, // system-wide monitoring + DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, + dispatch_get_main_queue()); + + dispatch_source_set_event_handler(m_memory_pressure_source, ^{ + dispatch_source_memorypressure_flags_t pressureLevel = + dispatch_source_get_data(m_memory_pressure_source); + if (pressureLevel & + (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) { + m_callback(); + } + }); + } + + void Stop() override { dispatch_source_cancel(m_memory_pressure_source); } + +private: + dispatch_source_t m_memory_pressure_source; +}; +#endif + +#if defined(__linux__) +static void MonitorThread(std::atomic<bool> &done, + MemoryMonitor::Callback callback) { + struct pollfd fds; + fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); + if (fds.fd < 0) + return; + fds.events = POLLPRI; + + auto cleanup = llvm::make_scope_exit([&]() { close(fds.fd); }); + + // Detect a 50ms stall in a 2 second time window. + const char trig[] = "some 50000 2000000"; + if (write(fds.fd, trig, strlen(trig) + 1) < 0) + return; + + while (!done) { + int n = poll(&fds, 1, 1000); + if (n > 0) { + if (fds.revents & POLLERR) + return; + if (fds.revents & POLLPRI) + callback(); + } + } +} + +class MemoryMonitorLinux : public MemoryMonitor { +public: + using MemoryMonitor::MemoryMonitor; + + void Start() override { + m_memory_pressure_thread = + std::thread(MonitorThread, std::ref(m_done), m_callback); + } + + void Stop() override { + if (m_memory_pressure_thread.joinable()) { + m_done = true; + m_memory_pressure_thread.join(); + } + } + +private: + std::atomic<bool> m_done = false; + std::thread m_memory_pressure_thread; +}; +#endif + +std::unique_ptr<MemoryMonitor> MemoryMonitor::Create(Callback callback) { +#if defined(__APPLE__) + return std::make_unique<MemoryMonitorDarwin>(callback); +#endif + +#if defined(__linux__) + return std::make_unique<MemoryMonitorLinux>(callback); +#endif + + return nullptr; +} diff --git a/lldb/tools/lldb-dap/MemoryMonitor.h b/lldb/tools/lldb-dap/MemoryMonitor.h new file mode 100644 index 0000000000000..e07c3bde9e85c --- /dev/null +++ b/lldb/tools/lldb-dap/MemoryMonitor.h @@ -0,0 +1,41 @@ +//===-- MemoryMonitor.h ---------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H +#define LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H + +#include <functional> +#include <memory> + +namespace lldb_dap { + +class MemoryMonitor { +public: + using Callback = std::function<void()>; + + MemoryMonitor(Callback callback) : m_callback(callback) {} + virtual ~MemoryMonitor() = default; + + /// MemoryMonitor is not copyable. + /// @{ + MemoryMonitor(const MemoryMonitor &) = delete; + MemoryMonitor &operator=(const MemoryMonitor &) = delete; + /// @} + + static std::unique_ptr<MemoryMonitor> Create(Callback callback); + + virtual void Start() = 0; + virtual void Stop() = 0; + +protected: + Callback m_callback; +}; + +} // namespace lldb_dap + +#endif diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index d005eccfae903..41405df548da2 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -9,7 +9,9 @@ #include "DAP.h" #include "EventHelper.h" #include "Handler/RequestHandler.h" +#include "MemoryMonitor.h" #include "RunInTerminal.h" +#include "lldb/API/SBDebugger.h" #include "lldb/API/SBStream.h" #include "lldb/Host/Config.h" #include "lldb/Host/File.h" @@ -504,9 +506,20 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + // Create a memory monitor. This can return nullptr if the host platform is + // not supported. + std::unique_ptr<MemoryMonitor> memory_monitor = MemoryMonitor::Create( + []() { lldb::SBDebugger::MemoryPressureDetected(); }); + + if (memory_monitor) + memory_monitor->Start(); + // Terminate the debugger before the C++ destructor chain kicks in. - auto terminate_debugger = - llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); }); + auto terminate_debugger = llvm::make_scope_exit([&] { + if (memory_monitor) + memory_monitor->Stop(); + lldb::SBDebugger::Terminate(); + }); std::vector<std::string> pre_init_commands; for (const std::string &arg : >From 59594877e40c60c29832f37a8ff5f1eb495f69f9 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Fri, 28 Feb 2025 17:07:55 -0600 Subject: [PATCH 2/6] Use the dispatch_get_global_queue and call dispatch_release --- lldb/tools/lldb-dap/MemoryMonitor.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lldb/tools/lldb-dap/MemoryMonitor.cpp b/lldb/tools/lldb-dap/MemoryMonitor.cpp index da3da42fe9b0f..a9118a89a82ac 100644 --- a/lldb/tools/lldb-dap/MemoryMonitor.cpp +++ b/lldb/tools/lldb-dap/MemoryMonitor.cpp @@ -33,7 +33,10 @@ class MemoryMonitorDarwin : public MemoryMonitor { DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, // system-wide monitoring DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, - dispatch_get_main_queue()); + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + + if (!m_memory_pressure_source) + return; dispatch_source_set_event_handler(m_memory_pressure_source, ^{ dispatch_source_memorypressure_flags_t pressureLevel = @@ -45,7 +48,12 @@ class MemoryMonitorDarwin : public MemoryMonitor { }); } - void Stop() override { dispatch_source_cancel(m_memory_pressure_source); } + void Stop() override { + if (m_memory_pressure_source) { + dispatch_source_cancel(m_memory_pressure_source); + dispatch_release(m_memory_pressure_source); + } + } private: dispatch_source_t m_memory_pressure_source; >From 05632355c720cb80891d13acc174d5a86ea0d823 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Mon, 3 Mar 2025 17:02:04 -0600 Subject: [PATCH 3/6] Move MemoryMonitor into Host --- .../lldb/Host}/MemoryMonitor.h | 8 +-- lldb/source/Host/CMakeLists.txt | 3 +- .../Host/common}/MemoryMonitor.cpp | 50 ++---------------- lldb/source/Host/macosx/objcxx/CMakeLists.txt | 1 + .../Host/macosx/objcxx/MemoryMonitorMacOSX.mm | 51 +++++++++++++++++++ lldb/tools/lldb-dap/CMakeLists.txt | 1 - lldb/tools/lldb-dap/lldb-dap.cpp | 7 +-- 7 files changed, 66 insertions(+), 55 deletions(-) rename lldb/{tools/lldb-dap => include/lldb/Host}/MemoryMonitor.h (87%) rename lldb/{tools/lldb-dap => source/Host/common}/MemoryMonitor.cpp (60%) create mode 100644 lldb/source/Host/macosx/objcxx/MemoryMonitorMacOSX.mm diff --git a/lldb/tools/lldb-dap/MemoryMonitor.h b/lldb/include/lldb/Host/MemoryMonitor.h similarity index 87% rename from lldb/tools/lldb-dap/MemoryMonitor.h rename to lldb/include/lldb/Host/MemoryMonitor.h index e07c3bde9e85c..504f5f9cba96b 100644 --- a/lldb/tools/lldb-dap/MemoryMonitor.h +++ b/lldb/include/lldb/Host/MemoryMonitor.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H -#define LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H +#ifndef LLDB_HOST_MEMORYMONITOR_H +#define LLDB_HOST_MEMORYMONITOR_H #include <functional> #include <memory> -namespace lldb_dap { +namespace lldb_private { class MemoryMonitor { public: @@ -36,6 +36,6 @@ class MemoryMonitor { Callback m_callback; }; -} // namespace lldb_dap +} // namespace lldb_private #endif diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index cdfb6184f2219..f4be151756b3b 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -27,6 +27,7 @@ add_host_subdirectory(common common/LockFileBase.cpp common/LZMA.cpp common/MainLoopBase.cpp + common/MemoryMonitor.cpp common/MonitoringProcessLauncher.cpp common/NativeProcessProtocol.cpp common/NativeRegisterContext.cpp @@ -136,7 +137,7 @@ else() elseif (CMAKE_SYSTEM_NAME MATCHES "AIX") add_host_subdirectory(aix aix/HostInfoAIX.cpp - ) + ) endif() endif() diff --git a/lldb/tools/lldb-dap/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp similarity index 60% rename from lldb/tools/lldb-dap/MemoryMonitor.cpp rename to lldb/source/Host/common/MemoryMonitor.cpp index a9118a89a82ac..7fa774b638415 100644 --- a/lldb/tools/lldb-dap/MemoryMonitor.cpp +++ b/lldb/source/Host/common/MemoryMonitor.cpp @@ -6,59 +6,20 @@ // //===----------------------------------------------------------------------===// -#include "MemoryMonitor.h" +#include "lldb/Host/MemoryMonitor.h" #include "llvm/ADT/ScopeExit.h" #include <atomic> #include <cstdio> #include <cstring> #include <thread> -#if defined(__APPLE__) -#include <dispatch/dispatch.h> -#endif - #if defined(__linux__) #include <fcntl.h> #include <poll.h> #include <unistd.h> #endif -using namespace lldb_dap; - -#if defined(__APPLE__) -class MemoryMonitorDarwin : public MemoryMonitor { - using MemoryMonitor::MemoryMonitor; - void Start() override { - m_memory_pressure_source = dispatch_source_create( - DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, - 0, // system-wide monitoring - DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); - - if (!m_memory_pressure_source) - return; - - dispatch_source_set_event_handler(m_memory_pressure_source, ^{ - dispatch_source_memorypressure_flags_t pressureLevel = - dispatch_source_get_data(m_memory_pressure_source); - if (pressureLevel & - (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) { - m_callback(); - } - }); - } - - void Stop() override { - if (m_memory_pressure_source) { - dispatch_source_cancel(m_memory_pressure_source); - dispatch_release(m_memory_pressure_source); - } - } - -private: - dispatch_source_t m_memory_pressure_source; -}; -#endif +using namespace lldb_private; #if defined(__linux__) static void MonitorThread(std::atomic<bool> &done, @@ -109,14 +70,11 @@ class MemoryMonitorLinux : public MemoryMonitor { }; #endif +#if !defined(__APPLE__) std::unique_ptr<MemoryMonitor> MemoryMonitor::Create(Callback callback) { -#if defined(__APPLE__) - return std::make_unique<MemoryMonitorDarwin>(callback); -#endif - #if defined(__linux__) return std::make_unique<MemoryMonitorLinux>(callback); #endif - return nullptr; } +#endif diff --git a/lldb/source/Host/macosx/objcxx/CMakeLists.txt b/lldb/source/Host/macosx/objcxx/CMakeLists.txt index 1e693bed12ce1..cda8269ca9efd 100644 --- a/lldb/source/Host/macosx/objcxx/CMakeLists.txt +++ b/lldb/source/Host/macosx/objcxx/CMakeLists.txt @@ -6,6 +6,7 @@ add_lldb_library(lldbHostMacOSXObjCXX NO_PLUGIN_DEPENDENCIES Host.mm HostInfoMacOSX.mm HostThreadMacOSX.mm + MemoryMonitorMacOSX.mm LINK_LIBS lldbUtility diff --git a/lldb/source/Host/macosx/objcxx/MemoryMonitorMacOSX.mm b/lldb/source/Host/macosx/objcxx/MemoryMonitorMacOSX.mm new file mode 100644 index 0000000000000..cb6c2457df1e3 --- /dev/null +++ b/lldb/source/Host/macosx/objcxx/MemoryMonitorMacOSX.mm @@ -0,0 +1,51 @@ +//===-- MemoryMonitorMacOSX.mm --------------------------------------------===// +// +// 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/MemoryMonitor.h" +#include <cassert> +#include <dispatch/dispatch.h> + +using namespace lldb_private; + +class MemoryMonitorMacOSX : public MemoryMonitor { + using MemoryMonitor::MemoryMonitor; + void Start() override { + m_memory_pressure_source = dispatch_source_create( + DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, + DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + + if (!m_memory_pressure_source) + return; + + dispatch_source_set_event_handler(m_memory_pressure_source, ^{ + dispatch_source_memorypressure_flags_t pressureLevel = + dispatch_source_get_data(m_memory_pressure_source); + if (pressureLevel & + (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) { + m_callback(); + } + }); + dispatch_activate(m_memory_pressure_source); + printf("Started\n"); + } + + void Stop() override { + if (m_memory_pressure_source) { + dispatch_source_cancel(m_memory_pressure_source); + dispatch_release(m_memory_pressure_source); + } + } + +private: + dispatch_source_t m_memory_pressure_source; +}; + +std::unique_ptr<MemoryMonitor> MemoryMonitor::Create(Callback callback) { + return std::make_unique<MemoryMonitorMacOSX>(callback); +} diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 8db377e31c3c6..8b3c520ec4360 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -36,7 +36,6 @@ add_lldb_tool(lldb-dap RunInTerminal.cpp SourceBreakpoint.cpp Watchpoint.cpp - MemoryMonitor.cpp Handler/ResponseHandler.cpp Handler/AttachRequestHandler.cpp diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index 41405df548da2..95d0efb1eef91 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -9,7 +9,6 @@ #include "DAP.h" #include "EventHelper.h" #include "Handler/RequestHandler.h" -#include "MemoryMonitor.h" #include "RunInTerminal.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBStream.h" @@ -17,6 +16,7 @@ #include "lldb/Host/File.h" #include "lldb/Host/MainLoop.h" #include "lldb/Host/MainLoopBase.h" +#include "lldb/Host/MemoryMonitor.h" #include "lldb/Host/Socket.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UriParser.h" @@ -508,8 +508,9 @@ int main(int argc, char *argv[]) { // Create a memory monitor. This can return nullptr if the host platform is // not supported. - std::unique_ptr<MemoryMonitor> memory_monitor = MemoryMonitor::Create( - []() { lldb::SBDebugger::MemoryPressureDetected(); }); + std::unique_ptr<lldb_private::MemoryMonitor> memory_monitor = + lldb_private::MemoryMonitor::Create( + []() { lldb::SBDebugger::MemoryPressureDetected(); }); if (memory_monitor) memory_monitor->Start(); >From 9209e108976bc1c321dfd9ce895d707d99b20fe5 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Mon, 3 Mar 2025 19:17:14 -0600 Subject: [PATCH 4/6] Use NativeThread and attempt a Windows implementation --- lldb/source/Host/common/MemoryMonitor.cpp | 106 ++++++++++++++-------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp index 7fa774b638415..9fced2684a85c 100644 --- a/lldb/source/Host/common/MemoryMonitor.cpp +++ b/lldb/source/Host/common/MemoryMonitor.cpp @@ -7,11 +7,16 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/MemoryMonitor.h" +#include "lldb/Host/HostThread.h" +#include "lldb/Host/ThreadLauncher.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/Support/Error.h" #include <atomic> +#include <cstddef> #include <cstdio> #include <cstring> -#include <thread> #if defined(__linux__) #include <fcntl.h> @@ -19,62 +24,87 @@ #include <unistd.h> #endif +#if defined(_WIN32) +#include <memoryapi.h> +#include <synchapi.h> +#endif + using namespace lldb_private; +class MemoryMonitorPoll : public MemoryMonitor { +public: + using MemoryMonitor::MemoryMonitor; + + lldb::thread_result_t MonitorThread() { #if defined(__linux__) -static void MonitorThread(std::atomic<bool> &done, - MemoryMonitor::Callback callback) { - struct pollfd fds; - fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); - if (fds.fd < 0) - return; - fds.events = POLLPRI; - - auto cleanup = llvm::make_scope_exit([&]() { close(fds.fd); }); - - // Detect a 50ms stall in a 2 second time window. - const char trig[] = "some 50000 2000000"; - if (write(fds.fd, trig, strlen(trig) + 1) < 0) - return; - - while (!done) { - int n = poll(&fds, 1, 1000); - if (n > 0) { - if (fds.revents & POLLERR) - return; - if (fds.revents & POLLPRI) - callback(); + struct pollfd fds; + fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); + if (fds.fd < 0) + return {}; + fds.events = POLLPRI; + + auto cleanup = llvm::make_scope_exit([&]() { close(fds.fd); }); + + // Detect a 50ms stall in a 2 second time window. + const char trig[] = "some 50000 2000000"; + if (write(fds.fd, trig, strlen(trig) + 1) < 0) + return {}; + + while (!m_done) { + int n = poll(&fds, 1, g_timeout); + if (n > 0) { + if (fds.revents & POLLERR) + return {}; + if (fds.revents & POLLPRI) + m_callback(); + } } - } -} +#endif -class MemoryMonitorLinux : public MemoryMonitor { -public: - using MemoryMonitor::MemoryMonitor; +#if defined(_WIN32) + HANDLE low_memory_notification = + CreateMemoryResourceNotification(LowMemoryResourceNotification); + if (!low_memory_notification) + return {}; + + while (!m_done) { + if (WaitForSingleObject(low_memory_notification, g_timeout) == + WAIT_OBJECT_0) { + m_callback(); + } + } +#endif + + return {}; + } void Start() override { - m_memory_pressure_thread = - std::thread(MonitorThread, std::ref(m_done), m_callback); + llvm::Expected<HostThread> memory_monitor_thread = + ThreadLauncher::LaunchThread("lldb.debugger.memory-monitor", + [this] { return MonitorThread(); }); + if (memory_monitor_thread) { + m_memory_monitor_thread = *memory_monitor_thread; + } else { + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), memory_monitor_thread.takeError(), + "failed to launch host thread: {0}"); + } } void Stop() override { - if (m_memory_pressure_thread.joinable()) { + if (m_memory_monitor_thread.IsJoinable()) { m_done = true; - m_memory_pressure_thread.join(); + m_memory_monitor_thread.Join(nullptr); } } private: + static constexpr uint32_t g_timeout = 1000; std::atomic<bool> m_done = false; - std::thread m_memory_pressure_thread; + HostThread m_memory_monitor_thread; }; -#endif #if !defined(__APPLE__) std::unique_ptr<MemoryMonitor> MemoryMonitor::Create(Callback callback) { -#if defined(__linux__) - return std::make_unique<MemoryMonitorLinux>(callback); -#endif - return nullptr; + return std::make_unique<MemoryMonitorPoll>(callback); } #endif >From f42780863a9dfbf66716aecf1c4c5ae0c2de7f81 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 4 Mar 2025 22:43:50 -0800 Subject: [PATCH 5/6] Include windows.h instead of memoryapi.h and synchapi.h --- lldb/source/Host/common/MemoryMonitor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp index 9fced2684a85c..932fa9c43a22c 100644 --- a/lldb/source/Host/common/MemoryMonitor.cpp +++ b/lldb/source/Host/common/MemoryMonitor.cpp @@ -25,8 +25,7 @@ #endif #if defined(_WIN32) -#include <memoryapi.h> -#include <synchapi.h> +#include <windows.h> #endif using namespace lldb_private; >From ad1e21175a3bdcc57d1ed7c6bcf455a1164613c4 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 4 Mar 2025 22:55:57 -0800 Subject: [PATCH 6/6] Log when memory pressure is detected --- lldb/tools/lldb-dap/lldb-dap.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index 95d0efb1eef91..a5d9978e30248 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -509,8 +509,11 @@ int main(int argc, char *argv[]) { // Create a memory monitor. This can return nullptr if the host platform is // not supported. std::unique_ptr<lldb_private::MemoryMonitor> memory_monitor = - lldb_private::MemoryMonitor::Create( - []() { lldb::SBDebugger::MemoryPressureDetected(); }); + lldb_private::MemoryMonitor::Create([&]() { + if (log) + *log << "memory pressure detected\n"; + lldb::SBDebugger::MemoryPressureDetected(); + }); if (memory_monitor) memory_monitor->Start(); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits