//===-- common_test.cpp -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "internal_defs.h" #include "tests/scudo_unit_test.h" #include "common.h" #include "mem_map.h" #include #include #include #include #include namespace scudo { static void getResidentPages(void *BaseAddress, size_t TotalPages, size_t *ResidentPages) { std::vector Pages(TotalPages, 0); ASSERT_EQ( 0, mincore(BaseAddress, TotalPages * getPageSizeCached(), Pages.data())) << strerror(errno); *ResidentPages = 0; for (unsigned char Value : Pages) { if (Value & 1) { ++*ResidentPages; } } } // Fuchsia needs getResidentPages implementation. TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) { // Make sure to have the size of the map on a page boundary. const uptr PageSize = getPageSizeCached(); const size_t NumPages = 1000; const uptr SizeBytes = NumPages * PageSize; MemMapT MemMap; ASSERT_TRUE(MemMap.map(/*Addr=*/0U, SizeBytes, "ResidentMemorySize")); ASSERT_NE(MemMap.getBase(), 0U); void *P = reinterpret_cast(MemMap.getBase()); size_t ResidentPages; getResidentPages(P, NumPages, &ResidentPages); EXPECT_EQ(0U, ResidentPages); // Make the entire map resident. memset(P, 1, SizeBytes); getResidentPages(P, NumPages, &ResidentPages); EXPECT_EQ(NumPages, ResidentPages); // Should release the memory to the kernel immediately. MemMap.releasePagesToOS(MemMap.getBase(), SizeBytes); getResidentPages(P, NumPages, &ResidentPages); EXPECT_EQ(0U, ResidentPages); // Make the entire map resident again. memset(P, 1, SizeBytes); getResidentPages(P, NumPages, &ResidentPages); EXPECT_EQ(NumPages, ResidentPages); MemMap.unmap(); } TEST(ScudoCommonTest, Zeros) { const uptr Size = 1ull << 20; MemMapT MemMap; ASSERT_TRUE(MemMap.map(/*Addr=*/0U, Size, "Zeros")); ASSERT_NE(MemMap.getBase(), 0U); uptr *P = reinterpret_cast(MemMap.getBase()); const ptrdiff_t N = Size / sizeof(uptr); EXPECT_EQ(std::count(P, P + N, 0), N); memset(P, 1, Size); EXPECT_EQ(std::count(P, P + N, 0), 0); MemMap.releasePagesToOS(MemMap.getBase(), Size); EXPECT_EQ(std::count(P, P + N, 0), N); MemMap.unmap(); } } // namespace scudo