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