#include <fcntl.h>
#include <linux/futex.h>
#include <sched.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
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;
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