1 //===-- common_test.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "internal_defs.h"
10 #include "tests/scudo_unit_test.h"
11 
12 #include "common.h"
13 #include <algorithm>
14 #include <fstream>
15 
16 namespace scudo {
17 
getResidentMemorySize()18 static uptr getResidentMemorySize() {
19   if (!SCUDO_LINUX)
20     UNREACHABLE("Not implemented!");
21   uptr Size;
22   uptr Resident;
23   std::ifstream IFS("/proc/self/statm");
24   IFS >> Size;
25   IFS >> Resident;
26   return Resident * getPageSizeCached();
27 }
28 
29 // Fuchsia needs getResidentMemorySize implementation.
TEST(ScudoCommonTest,SKIP_ON_FUCHSIA (ResidentMemorySize))30 TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) {
31   uptr OnStart = getResidentMemorySize();
32   EXPECT_GT(OnStart, 0UL);
33 
34   const uptr Size = 1ull << 30;
35   const uptr Threshold = Size >> 3;
36 
37   MapPlatformData Data = {};
38   void *P = map(nullptr, Size, "ResidentMemorySize", 0, &Data);
39   ASSERT_NE(nullptr, P);
40   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
41 
42   memset(P, 1, Size);
43   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
44 
45   releasePagesToOS((uptr)P, 0, Size, &Data);
46   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
47 
48   memset(P, 1, Size);
49   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
50 
51   unmap(P, Size, 0, &Data);
52 }
53 
TEST(ScudoCommonTest,Zeros)54 TEST(ScudoCommonTest, Zeros) {
55   const uptr Size = 1ull << 20;
56 
57   MapPlatformData Data = {};
58   uptr *P = reinterpret_cast<uptr *>(map(nullptr, Size, "Zeros", 0, &Data));
59   const ptrdiff_t N = Size / sizeof(*P);
60   ASSERT_NE(nullptr, P);
61   EXPECT_EQ(std::count(P, P + N, 0), N);
62 
63   memset(P, 1, Size);
64   EXPECT_EQ(std::count(P, P + N, 0), 0);
65 
66   releasePagesToOS((uptr)P, 0, Size, &Data);
67   EXPECT_EQ(std::count(P, P + N, 0), N);
68 
69   unmap(P, Size, 0, &Data);
70 }
71 
72 #if SCUDO_LINUX && !defined(__powerpc__)
73 // This test fails intermediately on PPC, which is why this test is disabled
74 // for now on this platform.
TEST(ScudoCommonTest,GetRssFromBuffer)75 TEST(ScudoCommonTest, GetRssFromBuffer) {
76   constexpr int64_t AllocSize = 10000000;
77   constexpr int64_t Error = 3000000;
78   constexpr size_t Runs = 10;
79 
80   int64_t Rss = scudo::GetRSS();
81   EXPECT_GT(Rss, 0);
82 
83   std::vector<std::unique_ptr<char[]>> Allocs(Runs);
84   for (auto &Alloc : Allocs) {
85     Alloc.reset(new char[AllocSize]());
86     int64_t Prev = Rss;
87     Rss = scudo::GetRSS();
88     EXPECT_LE(std::abs(Rss - AllocSize - Prev), Error);
89   }
90 }
91 #endif // SCUDO_LINUX
92 
93 } // namespace scudo
94