From: Bastian Kersting Date: Thu, 8 Dec 2022 20:22:42 +0000 (-0800) Subject: scudo-standalone: Add GetRSS method on Linux X-Git-Tag: upstream/17.0.6~24624 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cc02d61b459ff351fc785bd8154fc2e5beb95e92;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/compiler-rt/lib/scudo/standalone/common.cpp b/compiler-rt/lib/scudo/standalone/common.cpp index 666f954..67fd238 100644 --- a/compiler-rt/lib/scudo/standalone/common.cpp +++ b/compiler-rt/lib/scudo/standalone/common.cpp @@ -35,4 +35,8 @@ void NORETURN dieOnMapUnmapError(uptr SizeIfOOM) { die(); } +#if !SCUDO_LINUX +u64 GetRSS() { return 0; } +#endif + } // namespace scudo diff --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h index bc3dfec..3d70bad 100644 --- a/compiler-rt/lib/scudo/standalone/common.h +++ b/compiler-rt/lib/scudo/standalone/common.h @@ -132,6 +132,8 @@ u32 getNumberOfCPUs(); const char *getEnv(const char *Name); +u64 GetRSS(); + u64 getMonotonicTime(); u32 getThreadID(); diff --git a/compiler-rt/lib/scudo/standalone/linux.cpp b/compiler-rt/lib/scudo/standalone/linux.cpp index c77c1bb..4966b49 100644 --- a/compiler-rt/lib/scudo/standalone/linux.cpp +++ b/compiler-rt/lib/scudo/standalone/linux.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -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(*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; diff --git a/compiler-rt/lib/scudo/standalone/tests/common_test.cpp b/compiler-rt/lib/scudo/standalone/tests/common_test.cpp index 711e3b2..e459c7b 100644 --- a/compiler-rt/lib/scudo/standalone/tests/common_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/common_test.cpp @@ -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> Allocs(Runs); + for (auto &Alloc : Allocs) { + Alloc.reset(new char[AllocSize]()); + u64 Prev = Rss; + Rss = scudo::GetRSS(); + EXPECT_LE(std::abs(static_cast(Rss - AllocSize - Prev)), Error); + } +} +#endif // SCUDO_LINUX + } // namespace scudo