Skip to content

Commit 34b3ea3

Browse files
authored
[scudo] Make release to OS test more specific. (#147852)
The original version of ResidentMemorySize could be a little flaky. Replace the test with a version that verifies exactly how much of the map is resident.
1 parent b361885 commit 34b3ea3

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

compiler-rt/lib/scudo/standalone/tests/common_test.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,60 @@
1111

1212
#include "common.h"
1313
#include "mem_map.h"
14+
15+
#include <errno.h>
16+
#include <string.h>
17+
#include <sys/mman.h>
18+
1419
#include <algorithm>
15-
#include <fstream>
20+
#include <vector>
1621

1722
namespace scudo {
1823

19-
static uptr getResidentMemorySize() {
20-
if (!SCUDO_LINUX)
21-
UNREACHABLE("Not implemented!");
22-
uptr Size;
23-
uptr Resident;
24-
std::ifstream IFS("/proc/self/statm");
25-
IFS >> Size;
26-
IFS >> Resident;
27-
return Resident * getPageSizeCached();
24+
static void getResidentPages(void *BaseAddress, size_t TotalPages,
25+
size_t *ResidentPages) {
26+
std::vector<unsigned char> Pages(TotalPages, 0);
27+
ASSERT_EQ(
28+
0, mincore(BaseAddress, TotalPages * getPageSizeCached(), Pages.data()))
29+
<< strerror(errno);
30+
*ResidentPages = 0;
31+
for (unsigned char Value : Pages) {
32+
if (Value & 1) {
33+
++*ResidentPages;
34+
}
35+
}
2836
}
2937

30-
// Fuchsia needs getResidentMemorySize implementation.
38+
// Fuchsia needs getResidentPages implementation.
3139
TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) {
32-
uptr OnStart = getResidentMemorySize();
33-
EXPECT_GT(OnStart, 0UL);
34-
35-
const uptr Size = 1ull << 30;
36-
const uptr Threshold = Size >> 3;
40+
// Make sure to have the size of the map on a page boundary.
41+
const uptr PageSize = getPageSizeCached();
42+
const size_t NumPages = 1000;
43+
const uptr SizeBytes = NumPages * PageSize;
3744

3845
MemMapT MemMap;
39-
ASSERT_TRUE(MemMap.map(/*Addr=*/0U, Size, "ResidentMemorySize"));
46+
ASSERT_TRUE(MemMap.map(/*Addr=*/0U, SizeBytes, "ResidentMemorySize"));
4047
ASSERT_NE(MemMap.getBase(), 0U);
41-
void *P = reinterpret_cast<void *>(MemMap.getBase());
42-
EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
43-
44-
memset(P, 1, Size);
45-
EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
46-
47-
MemMap.releasePagesToOS(MemMap.getBase(), Size);
48-
EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
4948

50-
memset(P, 1, Size);
51-
EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
49+
void *P = reinterpret_cast<void *>(MemMap.getBase());
50+
size_t ResidentPages;
51+
getResidentPages(P, NumPages, &ResidentPages);
52+
EXPECT_EQ(0U, ResidentPages);
53+
54+
// Make the entire map resident.
55+
memset(P, 1, SizeBytes);
56+
getResidentPages(P, NumPages, &ResidentPages);
57+
EXPECT_EQ(NumPages, ResidentPages);
58+
59+
// Should release the memory to the kernel immediately.
60+
MemMap.releasePagesToOS(MemMap.getBase(), SizeBytes);
61+
getResidentPages(P, NumPages, &ResidentPages);
62+
EXPECT_EQ(0U, ResidentPages);
63+
64+
// Make the entire map resident again.
65+
memset(P, 1, SizeBytes);
66+
getResidentPages(P, NumPages, &ResidentPages);
67+
EXPECT_EQ(NumPages, ResidentPages);
5268

5369
MemMap.unmap();
5470
}

0 commit comments

Comments
 (0)