Skip to content

Commit

Permalink
scudo-standalone: Add GetRSS method on Linux
Browse files Browse the repository at this point in the history
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
  • Loading branch information
1c3t3a authored and vitalybuka committed Dec 8, 2022
1 parent c02782f commit cc02d61
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler-rt/lib/scudo/standalone/common.cpp
Expand Up @@ -35,4 +35,8 @@ void NORETURN dieOnMapUnmapError(uptr SizeIfOOM) {
die();
}

#if !SCUDO_LINUX
u64 GetRSS() { return 0; }
#endif

} // namespace scudo
2 changes: 2 additions & 0 deletions compiler-rt/lib/scudo/standalone/common.h
Expand Up @@ -132,6 +132,8 @@ u32 getNumberOfCPUs();

const char *getEnv(const char *Name);

u64 GetRSS();

u64 getMonotonicTime();

u32 getThreadID();
Expand Down
31 changes: 31 additions & 0 deletions compiler-rt/lib/scudo/standalone/linux.cpp
Expand Up @@ -19,6 +19,7 @@
#include <fcntl.h>
#include <linux/futex.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
Expand Down Expand Up @@ -180,6 +181,36 @@ bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) {
extern "C" WEAK int async_safe_write_log(int pri, const char *tag,
const char *msg);

static u64 GetRSSFromBuffer(const char *Buf) {
// The format of the file is:
// 1084 89 69 11 0 79 0
// We need the second number which is RSS in pages.
const char *Pos = Buf;
// Skip the first number.
while (*Pos >= '0' && *Pos <= '9')
Pos++;
// Skip whitespaces.
while (!(*Pos >= '0' && *Pos <= '9') && *Pos != 0)
Pos++;
// Read the number.
u64 Rss = 0;
for (; *Pos >= '0' && *Pos <= '9'; Pos++)
Rss = Rss * 10 + static_cast<u64>(*Pos) - '0';
return Rss * getPageSizeCached();
}

u64 GetRSS() {
auto Fd = open("/proc/self/statm", O_RDONLY);
char Buf[64];
s64 Len = read(Fd, Buf, sizeof(Buf) - 1);
close(Fd);
if (Len <= 0)
return 0;
Buf[Len] = 0;

return GetRSSFromBuffer(Buf);
}

void outputRaw(const char *Buffer) {
if (&async_safe_write_log) {
constexpr s32 AndroidLogInfo = 4;
Expand Down
19 changes: 19 additions & 0 deletions compiler-rt/lib/scudo/standalone/tests/common_test.cpp
Expand Up @@ -69,4 +69,23 @@ TEST(ScudoCommonTest, Zeros) {
unmap(P, Size, 0, &Data);
}

#if SCUDO_LINUX
TEST(ScudoCommonTest, GetRssFromBuffer) {
constexpr size_t AllocSize = 10000000;
constexpr u64 Error = 3000000;
constexpr size_t Runs = 10;

u64 Rss = scudo::GetRSS();
EXPECT_GT(Rss, 0);

std::vector<std::unique_ptr<char[]>> Allocs(Runs);
for (auto &Alloc : Allocs) {
Alloc.reset(new char[AllocSize]());
u64 Prev = Rss;
Rss = scudo::GetRSS();
EXPECT_LE(std::abs(static_cast<int64_t>(Rss - AllocSize - Prev)), Error);
}
}
#endif // SCUDO_LINUX

} // namespace scudo

0 comments on commit cc02d61

Please sign in to comment.