Skip to content

Commit cc02d61

Browse files
1c3t3avitalybuka
authored andcommitted
scudo-standalone: Add GetRSS method on Linux
This change adds a GetRSS method on Linux that parses the number from /proc/self/statm. This change is part of splitting up https://reviews.llvm.org/D126752. Reviewed By: vitalybuka, cryptoad Differential Revision: https://reviews.llvm.org/D139430
1 parent c02782f commit cc02d61

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

compiler-rt/lib/scudo/standalone/common.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ void NORETURN dieOnMapUnmapError(uptr SizeIfOOM) {
3535
die();
3636
}
3737

38+
#if !SCUDO_LINUX
39+
u64 GetRSS() { return 0; }
40+
#endif
41+
3842
} // namespace scudo

compiler-rt/lib/scudo/standalone/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ u32 getNumberOfCPUs();
132132

133133
const char *getEnv(const char *Name);
134134

135+
u64 GetRSS();
136+
135137
u64 getMonotonicTime();
136138

137139
u32 getThreadID();

compiler-rt/lib/scudo/standalone/linux.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <fcntl.h>
2020
#include <linux/futex.h>
2121
#include <sched.h>
22+
#include <stdio.h>
2223
#include <stdlib.h>
2324
#include <string.h>
2425
#include <sys/mman.h>
@@ -180,6 +181,36 @@ bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) {
180181
extern "C" WEAK int async_safe_write_log(int pri, const char *tag,
181182
const char *msg);
182183

184+
static u64 GetRSSFromBuffer(const char *Buf) {
185+
// The format of the file is:
186+
// 1084 89 69 11 0 79 0
187+
// We need the second number which is RSS in pages.
188+
const char *Pos = Buf;
189+
// Skip the first number.
190+
while (*Pos >= '0' && *Pos <= '9')
191+
Pos++;
192+
// Skip whitespaces.
193+
while (!(*Pos >= '0' && *Pos <= '9') && *Pos != 0)
194+
Pos++;
195+
// Read the number.
196+
u64 Rss = 0;
197+
for (; *Pos >= '0' && *Pos <= '9'; Pos++)
198+
Rss = Rss * 10 + static_cast<u64>(*Pos) - '0';
199+
return Rss * getPageSizeCached();
200+
}
201+
202+
u64 GetRSS() {
203+
auto Fd = open("/proc/self/statm", O_RDONLY);
204+
char Buf[64];
205+
s64 Len = read(Fd, Buf, sizeof(Buf) - 1);
206+
close(Fd);
207+
if (Len <= 0)
208+
return 0;
209+
Buf[Len] = 0;
210+
211+
return GetRSSFromBuffer(Buf);
212+
}
213+
183214
void outputRaw(const char *Buffer) {
184215
if (&async_safe_write_log) {
185216
constexpr s32 AndroidLogInfo = 4;

compiler-rt/lib/scudo/standalone/tests/common_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,23 @@ TEST(ScudoCommonTest, Zeros) {
6969
unmap(P, Size, 0, &Data);
7070
}
7171

72+
#if SCUDO_LINUX
73+
TEST(ScudoCommonTest, GetRssFromBuffer) {
74+
constexpr size_t AllocSize = 10000000;
75+
constexpr u64 Error = 3000000;
76+
constexpr size_t Runs = 10;
77+
78+
u64 Rss = scudo::GetRSS();
79+
EXPECT_GT(Rss, 0);
80+
81+
std::vector<std::unique_ptr<char[]>> Allocs(Runs);
82+
for (auto &Alloc : Allocs) {
83+
Alloc.reset(new char[AllocSize]());
84+
u64 Prev = Rss;
85+
Rss = scudo::GetRSS();
86+
EXPECT_LE(std::abs(static_cast<int64_t>(Rss - AllocSize - Prev)), Error);
87+
}
88+
}
89+
#endif // SCUDO_LINUX
90+
7291
} // namespace scudo

0 commit comments

Comments
 (0)