[Lldb-commits] [lldb] [lldb] Fix Linux memory monitor. (PR #182011)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 18 08:59:06 PST 2026
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/182011
>From cbf20d3fa92d7c0cc239f885fa8914fc2fea8f2a Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 18 Feb 2026 11:25:35 +0000
Subject: [PATCH 1/3] [lldb] Fix Linux memory monitor.
Only call the callback when we are actually low on memory.
Increase the threshold to 200ms in a 2 second interval to match
systemd's default see
[DefaultMemoryPressureWatch](https://www.freedesktop.org/software/systemd/man/latest/systemd-system.conf.html#DefaultMemoryPressureWatch=).
---
lldb/source/Host/common/MemoryMonitor.cpp | 48 ++++++++++++++++++++---
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp
index 7734be8688675..82b5356c9983b 100644
--- a/lldb/source/Host/common/MemoryMonitor.cpp
+++ b/lldb/source/Host/common/MemoryMonitor.cpp
@@ -18,6 +18,8 @@
#include <cstring>
#if defined(__linux__)
+#include "lldb/Host/posix/Support.h"
+#include "llvm/Support/LineIterator.h"
#include <fcntl.h>
#include <poll.h>
#include <sys/eventfd.h>
@@ -44,7 +46,7 @@ class MemoryMonitorLinux : public MemoryMonitor {
~MemoryMonitorLinux() {
if (m_memory_monitor_thread.IsJoinable())
m_memory_monitor_thread.Join(nullptr);
- if (m_stop_fd != 1)
+ if (m_stop_fd != -1)
::close(m_stop_fd);
}
@@ -96,8 +98,8 @@ class MemoryMonitorLinux : public MemoryMonitor {
llvm::scope_exit cleanup([&]() { ::close(pfds[pressure_idx].fd); });
- // Detect a 50ms stall in a 2 second time window.
- constexpr llvm::StringRef trigger = "some 50000 2000000";
+ // Detect a 200ms stall in a 2 second time window.
+ constexpr llvm::StringRef trigger = "some 200000 2000000";
if (::write(pfds[pressure_idx].fd, trigger.data(), trigger.size() + 1) < 0)
return {};
@@ -109,14 +111,50 @@ class MemoryMonitorLinux : public MemoryMonitor {
if (pfds[stop_idx].revents & (POLLIN | POLLERR))
return {};
- if (pfds[pressure_idx].revents & POLLERR)
+ const short pressure_revents = pfds[stop_idx].revents;
+ if (pressure_revents & POLLERR)
return {};
- if (pfds[pressure_idx].revents & POLLPRI)
+ if ((pressure_revents & POLLPRI) && isLowMemory())
m_callback();
}
}
return {};
}
+
+ static bool isLowMemory() {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> bufferOrErr =
+ getProcFile("meminfo");
+
+ if (!bufferOrErr)
+ return false;
+
+ uint64_t mem_total = 0;
+ uint64_t mem_available = 0;
+ const int radix = 10;
+
+ for (llvm::line_iterator iter(**bufferOrErr, true); !iter.is_at_end();
+ ++iter) {
+ llvm::StringRef line = *iter;
+ if (line.consume_front("MemTotal:")) {
+ line.ltrim().consumeInteger(radix, mem_total);
+ continue;
+ }
+
+ if (line.consume_front("MemAvailable:")) {
+ line.ltrim().consumeInteger(radix, mem_available);
+ // MemAvailable comes after MemTotal.
+ break;
+ }
+ }
+
+ if (mem_total == 0 || mem_available == 0)
+ return false;
+
+ const uint64_t approx_memory_percent = (mem_available * 100) / mem_total;
+ const uint64_t low_memory_percent = 20;
+ return approx_memory_percent < low_memory_percent;
+ }
+
int m_stop_fd = -1;
HostThread m_memory_monitor_thread;
};
>From 942526aa6939f3001dab56f63a934ef8181ea5ca Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 18 Feb 2026 15:24:59 +0000
Subject: [PATCH 2/3] add review changes
---
lldb/source/Host/common/MemoryMonitor.cpp | 27 ++++++++++++-----------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp
index 82b5356c9983b..49e568aa26590 100644
--- a/lldb/source/Host/common/MemoryMonitor.cpp
+++ b/lldb/source/Host/common/MemoryMonitor.cpp
@@ -114,41 +114,42 @@ class MemoryMonitorLinux : public MemoryMonitor {
const short pressure_revents = pfds[stop_idx].revents;
if (pressure_revents & POLLERR)
return {};
- if ((pressure_revents & POLLPRI) && isLowMemory())
- m_callback();
+ if (pressure_revents & POLLPRI) {
+ if (const std::optional<bool> is_low_opt = IsLowMemory();
+ is_low_opt && *is_low_opt)
+ m_callback();
+ }
}
}
return {};
}
- static bool isLowMemory() {
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> bufferOrErr =
+ static std::optional<bool> IsLowMemory() {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer_or_err =
getProcFile("meminfo");
- if (!bufferOrErr)
- return false;
+ if (!buffer_or_err)
+ return std::nullopt;
uint64_t mem_total = 0;
uint64_t mem_available = 0;
const int radix = 10;
- for (llvm::line_iterator iter(**bufferOrErr, true); !iter.is_at_end();
+ for (llvm::line_iterator iter(**buffer_or_err, true); !iter.is_at_end();
++iter) {
llvm::StringRef line = *iter;
if (line.consume_front("MemTotal:")) {
line.ltrim().consumeInteger(radix, mem_total);
- continue;
+ } else if (line.consume_front("MemAvailable:")) {
+ line.ltrim().consumeInteger(radix, mem_available);
}
- if (line.consume_front("MemAvailable:")) {
- line.ltrim().consumeInteger(radix, mem_available);
- // MemAvailable comes after MemTotal.
+ if (mem_total && mem_available)
break;
- }
}
if (mem_total == 0 || mem_available == 0)
- return false;
+ return std::nullopt;
const uint64_t approx_memory_percent = (mem_available * 100) / mem_total;
const uint64_t low_memory_percent = 20;
>From 33554bcebf3c9b329ff44835a2bdff9505cb9ecb Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 18 Feb 2026 16:58:38 +0000
Subject: [PATCH 3/3] add review changes
---
lldb/source/Host/common/MemoryMonitor.cpp | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp
index 49e568aa26590..1bdc0ff2fc7e8 100644
--- a/lldb/source/Host/common/MemoryMonitor.cpp
+++ b/lldb/source/Host/common/MemoryMonitor.cpp
@@ -134,23 +134,29 @@ class MemoryMonitorLinux : public MemoryMonitor {
uint64_t mem_total = 0;
uint64_t mem_available = 0;
const int radix = 10;
+ bool parse_error = false;
for (llvm::line_iterator iter(**buffer_or_err, true); !iter.is_at_end();
++iter) {
llvm::StringRef line = *iter;
- if (line.consume_front("MemTotal:")) {
- line.ltrim().consumeInteger(radix, mem_total);
- } else if (line.consume_front("MemAvailable:")) {
- line.ltrim().consumeInteger(radix, mem_available);
- }
+ if (line.consume_front("MemTotal:"))
+ parse_error = line.ltrim().consumeInteger(radix, mem_total);
+ else if (line.consume_front("MemAvailable:"))
+ parse_error = line.ltrim().consumeInteger(radix, mem_available);
+
+ if (parse_error)
+ return std::nullopt;
if (mem_total && mem_available)
break;
}
- if (mem_total == 0 || mem_available == 0)
+ if (mem_total == 0)
return std::nullopt;
+ if (mem_available == 0) // We are actually out of memory.
+ return true;
+
const uint64_t approx_memory_percent = (mem_available * 100) / mem_total;
const uint64_t low_memory_percent = 20;
return approx_memory_percent < low_memory_percent;
More information about the lldb-commits
mailing list