Enable guard pages in CHECK_CLIENT
Change the behaviour to use PROT_NONE for reservations in CHECK_CLIENT mode. This means that we only provide access once data is actually being used.
This commit is contained in:
committed by
Matthew Parkinson
parent
02d2ab8f7e
commit
9df0101dfd
@@ -50,13 +50,6 @@ int main() {
|
|||||||
}
|
}
|
||||||
" SNMALLOC_PLATFORM_HAS_GETENTROPY)
|
" SNMALLOC_PLATFORM_HAS_GETENTROPY)
|
||||||
|
|
||||||
if (NOT SNMALLOC_CI_BUILD)
|
|
||||||
option(USE_POSIX_COMMIT_CHECKS "Instrument Posix PAL to check for access to unused blocks of memory." Off)
|
|
||||||
else ()
|
|
||||||
# This is enabled in every bit of CI to detect errors.
|
|
||||||
option(USE_POSIX_COMMIT_CHECKS "Instrument Posix PAL to check for access to unused blocks of memory." On)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Provide as macro so other projects can reuse
|
# Provide as macro so other projects can reuse
|
||||||
macro(warnings_high)
|
macro(warnings_high)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
@@ -169,10 +162,6 @@ if(SNMALLOC_CI_BUILD)
|
|||||||
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_CI_BUILD)
|
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_CI_BUILD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_POSIX_COMMIT_CHECKS)
|
|
||||||
target_compile_definitions(snmalloc_lib INTERFACE -DUSE_POSIX_COMMIT_CHECKS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(SNMALLOC_PLATFORM_HAS_GETENTROPY)
|
if(SNMALLOC_PLATFORM_HAS_GETENTROPY)
|
||||||
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_PLATFORM_HAS_GETENTROPY)
|
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_PLATFORM_HAS_GETENTROPY)
|
||||||
endif()
|
endif()
|
||||||
@@ -277,13 +266,13 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
|
|||||||
set(SHARED_FILES src/override/new.cc)
|
set(SHARED_FILES src/override/new.cc)
|
||||||
add_shim(snmallocshim SHARED ${SHARED_FILES})
|
add_shim(snmallocshim SHARED ${SHARED_FILES})
|
||||||
add_shim(snmallocshim-checks SHARED ${SHARED_FILES})
|
add_shim(snmallocshim-checks SHARED ${SHARED_FILES})
|
||||||
target_compile_definitions(snmallocshim-checks PRIVATE CHECK_CLIENT)
|
target_compile_definitions(snmallocshim-checks PRIVATE SNMALLOC_CHECK_CLIENT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SNMALLOC_RUST_SUPPORT)
|
if(SNMALLOC_RUST_SUPPORT)
|
||||||
add_shim(snmallocshim-rust STATIC src/override/rust.cc)
|
add_shim(snmallocshim-rust STATIC src/override/rust.cc)
|
||||||
add_shim(snmallocshim-checks-rust STATIC src/override/rust.cc)
|
add_shim(snmallocshim-checks-rust STATIC src/override/rust.cc)
|
||||||
target_compile_definitions(snmallocshim-checks-rust PRIVATE CHECK_CLIENT)
|
target_compile_definitions(snmallocshim-checks-rust PRIVATE SNMALLOC_CHECK_CLIENT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
@@ -313,14 +302,11 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
|
|||||||
|
|
||||||
add_executable(${TESTNAME} ${SRC})
|
add_executable(${TESTNAME} ${SRC})
|
||||||
|
|
||||||
# For all tests enable commit checking.
|
|
||||||
target_compile_definitions(${TESTNAME} PRIVATE -DUSE_POSIX_COMMIT_CHECKS)
|
|
||||||
|
|
||||||
if (${FLAVOUR} STREQUAL "malloc")
|
if (${FLAVOUR} STREQUAL "malloc")
|
||||||
target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_PASS_THROUGH)
|
target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_PASS_THROUGH)
|
||||||
endif()
|
endif()
|
||||||
if (${FLAVOUR} STREQUAL "check")
|
if (${FLAVOUR} STREQUAL "check")
|
||||||
target_compile_definitions(${TESTNAME} PRIVATE CHECK_CLIENT)
|
target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_CHECK_CLIENT)
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(${TESTNAME} snmalloc_lib)
|
target_link_libraries(${TESTNAME} snmalloc_lib)
|
||||||
if (${TEST} MATCHES "release-.*")
|
if (${TEST} MATCHES "release-.*")
|
||||||
|
|||||||
@@ -114,12 +114,6 @@ namespace snmalloc
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// // The CHECK_CLIENT macro is used to turn on minimal checking of the client
|
|
||||||
// // calling the API correctly.
|
|
||||||
// #if !defined(NDEBUG) && !defined(CHECK_CLIENT)
|
|
||||||
// # define CHECK_CLIENT
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
inline SNMALLOC_FAST_PATH void check_client_error(const char* const str)
|
inline SNMALLOC_FAST_PATH void check_client_error(const char* const str)
|
||||||
{
|
{
|
||||||
//[[clang::musttail]]
|
//[[clang::musttail]]
|
||||||
@@ -132,7 +126,7 @@ check_client_impl(bool test, const char* const str)
|
|||||||
if (unlikely(!test))
|
if (unlikely(!test))
|
||||||
check_client_error(str);
|
check_client_error(str);
|
||||||
}
|
}
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
# define check_client(test, str) check_client_impl(test, str)
|
# define check_client(test, str) check_client_impl(test, str)
|
||||||
#else
|
#else
|
||||||
# define check_client(test, str)
|
# define check_client(test, str)
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace snmalloc
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
template<size_t length, typename T>
|
template<size_t length, typename T>
|
||||||
class ModArray
|
class ModArray
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace snmalloc
|
|||||||
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
|
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
|
||||||
|
|
||||||
// Minimum number of objects on a slab
|
// Minimum number of objects on a slab
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
static constexpr size_t MIN_OBJECT_COUNT = 13;
|
static constexpr size_t MIN_OBJECT_COUNT = 13;
|
||||||
#else
|
#else
|
||||||
static constexpr size_t MIN_OBJECT_COUNT = 4;
|
static constexpr size_t MIN_OBJECT_COUNT = 4;
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ namespace snmalloc
|
|||||||
FreeListBuilder<false> b;
|
FreeListBuilder<false> b;
|
||||||
SNMALLOC_ASSERT(b.empty());
|
SNMALLOC_ASSERT(b.empty());
|
||||||
|
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// Structure to represent the temporary list elements
|
// Structure to represent the temporary list elements
|
||||||
struct PreAllocObject
|
struct PreAllocObject
|
||||||
{
|
{
|
||||||
@@ -214,7 +214,7 @@ namespace snmalloc
|
|||||||
meta->free_queue.close(fl, key);
|
meta->free_queue.close(fl, key);
|
||||||
void* p = finish_alloc_no_zero(fl.take(key), sizeclass);
|
void* p = finish_alloc_no_zero(fl.take(key), sizeclass);
|
||||||
|
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// Check free list is well-formed on platforms with
|
// Check free list is well-formed on platforms with
|
||||||
// integers as pointers.
|
// integers as pointers.
|
||||||
size_t count = 1; // Already taken one above.
|
size_t count = 1; // Already taken one above.
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace snmalloc
|
|||||||
// TODO: Should really use C++20 atomic_ref rather than a union.
|
// TODO: Should really use C++20 atomic_ref rather than a union.
|
||||||
AtomicCapPtr<FreeObject, CBAlloc> atomic_next_object;
|
AtomicCapPtr<FreeObject, CBAlloc> atomic_next_object;
|
||||||
};
|
};
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// Encoded representation of a back pointer.
|
// Encoded representation of a back pointer.
|
||||||
// Hard to fake, and provides consistency on
|
// Hard to fake, and provides consistency on
|
||||||
// the next pointers.
|
// the next pointers.
|
||||||
@@ -104,7 +104,7 @@ namespace snmalloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign next_object and update its prev_encoded if CHECK_CLIENT.
|
* Assign next_object and update its prev_encoded if SNMALLOC_CHECK_CLIENT.
|
||||||
* Static so that it can be used on reference to a FreeObject.
|
* Static so that it can be used on reference to a FreeObject.
|
||||||
*
|
*
|
||||||
* Returns a pointer to the next_object field of the next parameter as an
|
* Returns a pointer to the next_object field of the next parameter as an
|
||||||
@@ -116,7 +116,7 @@ namespace snmalloc
|
|||||||
CapPtr<FreeObject, CBAlloc> next,
|
CapPtr<FreeObject, CBAlloc> next,
|
||||||
FreeListKey& key)
|
FreeListKey& key)
|
||||||
{
|
{
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
next->prev_encoded =
|
next->prev_encoded =
|
||||||
signed_prev(address_cast(curr), address_cast(next), key);
|
signed_prev(address_cast(curr), address_cast(next), key);
|
||||||
#else
|
#else
|
||||||
@@ -127,13 +127,13 @@ namespace snmalloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign next_object and update its prev_encoded if CHECK_CLIENT
|
* Assign next_object and update its prev_encoded if SNMALLOC_CHECK_CLIENT
|
||||||
*
|
*
|
||||||
* Uses the atomic view of next, so can be used in the message queues.
|
* Uses the atomic view of next, so can be used in the message queues.
|
||||||
*/
|
*/
|
||||||
void atomic_store_next(CapPtr<FreeObject, CBAlloc> next, FreeListKey& key)
|
void atomic_store_next(CapPtr<FreeObject, CBAlloc> next, FreeListKey& key)
|
||||||
{
|
{
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
next->prev_encoded =
|
next->prev_encoded =
|
||||||
signed_prev(address_cast(this), address_cast(next), key);
|
signed_prev(address_cast(this), address_cast(next), key);
|
||||||
#else
|
#else
|
||||||
@@ -152,7 +152,7 @@ namespace snmalloc
|
|||||||
CapPtr<FreeObject, CBAlloc> atomic_read_next(FreeListKey& key)
|
CapPtr<FreeObject, CBAlloc> atomic_read_next(FreeListKey& key)
|
||||||
{
|
{
|
||||||
auto n = atomic_next_object.load(std::memory_order_acquire);
|
auto n = atomic_next_object.load(std::memory_order_acquire);
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
if (n != nullptr)
|
if (n != nullptr)
|
||||||
{
|
{
|
||||||
n->check_prev(signed_prev(address_cast(this), address_cast(n), key));
|
n->check_prev(signed_prev(address_cast(this), address_cast(n), key));
|
||||||
@@ -194,7 +194,7 @@ namespace snmalloc
|
|||||||
class FreeListIter
|
class FreeListIter
|
||||||
{
|
{
|
||||||
CapPtr<FreeObject, CBAlloc> curr{nullptr};
|
CapPtr<FreeObject, CBAlloc> curr{nullptr};
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
address_t prev{0};
|
address_t prev{0};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ namespace snmalloc
|
|||||||
CapPtr<FreeObject, CBAlloc> head, address_t prev_value)
|
CapPtr<FreeObject, CBAlloc> head, address_t prev_value)
|
||||||
: curr(head)
|
: curr(head)
|
||||||
{
|
{
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
prev = prev_value;
|
prev = prev_value;
|
||||||
#endif
|
#endif
|
||||||
UNUSED(prev_value);
|
UNUSED(prev_value);
|
||||||
@@ -237,7 +237,7 @@ namespace snmalloc
|
|||||||
|
|
||||||
Aal::prefetch(next.unsafe_ptr());
|
Aal::prefetch(next.unsafe_ptr());
|
||||||
curr = next;
|
curr = next;
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
c->check_prev(prev);
|
c->check_prev(prev);
|
||||||
prev = signed_prev(address_cast(c), address_cast(next), key);
|
prev = signed_prev(address_cast(c), address_cast(next), key);
|
||||||
#else
|
#else
|
||||||
@@ -251,7 +251,7 @@ namespace snmalloc
|
|||||||
/**
|
/**
|
||||||
* Used to build a free list in object space.
|
* Used to build a free list in object space.
|
||||||
*
|
*
|
||||||
* Adds signing of pointers in the CHECK_CLIENT mode
|
* Adds signing of pointers in the SNMALLOC_CHECK_CLIENT mode
|
||||||
*
|
*
|
||||||
* We use the template parameter, so that an enclosing
|
* We use the template parameter, so that an enclosing
|
||||||
* class can make use of the remaining bytes, which may not
|
* class can make use of the remaining bytes, which may not
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace snmalloc
|
|||||||
*
|
*
|
||||||
* Spare 32bits are used for the fields in MetaslabEnd.
|
* Spare 32bits are used for the fields in MetaslabEnd.
|
||||||
*/
|
*/
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
FreeListBuilder<true> free_queue;
|
FreeListBuilder<true> free_queue;
|
||||||
#else
|
#else
|
||||||
FreeListBuilder<false> free_queue;
|
FreeListBuilder<false> free_queue;
|
||||||
@@ -149,7 +149,7 @@ namespace snmalloc
|
|||||||
auto p = tmp_fl.take(key);
|
auto p = tmp_fl.take(key);
|
||||||
fast_free_list = tmp_fl;
|
fast_free_list = tmp_fl;
|
||||||
|
|
||||||
#ifdef CHECK_CLIENT
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
entropy.refresh_bits();
|
entropy.refresh_bits();
|
||||||
#else
|
#else
|
||||||
UNUSED(entropy);
|
UNUSED(entropy);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ namespace snmalloc
|
|||||||
*/
|
*/
|
||||||
inline uint16_t threshold_for_waking_slab(sizeclass_t sizeclass)
|
inline uint16_t threshold_for_waking_slab(sizeclass_t sizeclass)
|
||||||
{
|
{
|
||||||
// #ifdef CHECK_CLIENT
|
// #ifdef SNMALLOC_CHECK_CLIENT
|
||||||
return sizeclass_metadata.waking[sizeclass];
|
return sizeclass_metadata.waking[sizeclass];
|
||||||
// #else
|
// #else
|
||||||
// UNUSED(sizeclass);
|
// UNUSED(sizeclass);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ namespace snmalloc
|
|||||||
{
|
{
|
||||||
SNMALLOC_ASSERT(is_aligned_block<page_size>(p, size));
|
SNMALLOC_ASSERT(is_aligned_block<page_size>(p, size));
|
||||||
|
|
||||||
# ifdef USE_POSIX_COMMIT_CHECKS
|
# if defined(SNMALLOC_CHECK_CLIENT) && !defined(NDEBUG)
|
||||||
memset(p, 0x5a, size);
|
memset(p, 0x5a, size);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ namespace snmalloc
|
|||||||
while (madvise(p, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN)
|
while (madvise(p, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN)
|
||||||
;
|
;
|
||||||
|
|
||||||
# ifdef USE_POSIX_COMMIT_CHECKS
|
# ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// This must occur after `MADV_FREE_REUSABLE`.
|
// This must occur after `MADV_FREE_REUSABLE`.
|
||||||
//
|
//
|
||||||
// `mach_vm_protect` is observably slower in benchmarks.
|
// `mach_vm_protect` is observably slower in benchmarks.
|
||||||
@@ -179,7 +179,7 @@ namespace snmalloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef USE_POSIX_COMMIT_CHECKS
|
# ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// Mark pages as writable for `madvise` below.
|
// Mark pages as writable for `madvise` below.
|
||||||
//
|
//
|
||||||
// `mach_vm_protect` is observably slower in benchmarks.
|
// `mach_vm_protect` is observably slower in benchmarks.
|
||||||
@@ -218,7 +218,7 @@ namespace snmalloc
|
|||||||
// must be initialized to 0 or addr is interepreted as a lower-bound.
|
// must be initialized to 0 or addr is interepreted as a lower-bound.
|
||||||
mach_vm_address_t addr = 0;
|
mach_vm_address_t addr = 0;
|
||||||
|
|
||||||
# ifdef USE_POSIX_COMMIT_CHECKS
|
# ifdef SNMALLOC_CHECK_CLIENT
|
||||||
vm_prot_t prot = committed ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_NONE;
|
vm_prot_t prot = committed ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_NONE;
|
||||||
# else
|
# else
|
||||||
vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
|
vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ namespace snmalloc
|
|||||||
{
|
{
|
||||||
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
|
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
|
||||||
// Call this Pal to simulate the Windows decommit in CI.
|
// Call this Pal to simulate the Windows decommit in CI.
|
||||||
#ifdef USE_POSIX_COMMIT_CHECKS
|
#if defined(SNMALLOC_CHECK_CLIENT) && !defined(NDEBUG)
|
||||||
memset(p, 0x5a, size);
|
memset(p, 0x5a, size);
|
||||||
#endif
|
#endif
|
||||||
madvise(p, size, MADV_FREE);
|
madvise(p, size, MADV_FREE);
|
||||||
#ifdef USE_POSIX_COMMIT_CHECKS
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
mprotect(p, size, PROT_NONE);
|
mprotect(p, size, PROT_NONE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,16 @@ namespace snmalloc
|
|||||||
|
|
||||||
int log2align = static_cast<int>(bits::next_pow2_bits(size));
|
int log2align = static_cast<int>(bits::next_pow2_bits(size));
|
||||||
|
|
||||||
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
|
auto prot = committed ? PROT_READ | PROT_WRITE : PROT_NONE;
|
||||||
|
#else
|
||||||
|
auto prot = PROT_READ | PROT_WRITE;
|
||||||
|
#endif
|
||||||
|
|
||||||
void* p = mmap(
|
void* p = mmap(
|
||||||
nullptr,
|
nullptr,
|
||||||
size,
|
size,
|
||||||
PROT_READ | PROT_WRITE,
|
prot,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align),
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align),
|
||||||
-1,
|
-1,
|
||||||
0);
|
0);
|
||||||
|
|||||||
@@ -165,10 +165,12 @@ namespace snmalloc
|
|||||||
static void notify_not_using(void* p, size_t size) noexcept
|
static void notify_not_using(void* p, size_t size) noexcept
|
||||||
{
|
{
|
||||||
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
|
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
|
||||||
#ifdef USE_POSIX_COMMIT_CHECKS
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
// Fill memory so that when we switch the pages back on we don't make
|
// Fill memory so that when we switch the pages back on we don't make
|
||||||
// assumptions on the content.
|
// assumptions on the content.
|
||||||
|
# if !defined(NDEBUG)
|
||||||
memset(p, 0x5a, size);
|
memset(p, 0x5a, size);
|
||||||
|
# endif
|
||||||
mprotect(p, size, PROT_NONE);
|
mprotect(p, size, PROT_NONE);
|
||||||
#else
|
#else
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
@@ -189,7 +191,7 @@ namespace snmalloc
|
|||||||
SNMALLOC_ASSERT(
|
SNMALLOC_ASSERT(
|
||||||
is_aligned_block<OS::page_size>(p, size) || (zero_mem == NoZero));
|
is_aligned_block<OS::page_size>(p, size) || (zero_mem == NoZero));
|
||||||
|
|
||||||
#ifdef USE_POSIX_COMMIT_CHECKS
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
mprotect(p, size, PROT_READ | PROT_WRITE);
|
mprotect(p, size, PROT_READ | PROT_WRITE);
|
||||||
#else
|
#else
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
@@ -260,6 +262,12 @@ namespace snmalloc
|
|||||||
constexpr size_t min_size =
|
constexpr size_t min_size =
|
||||||
bits::is64() ? bits::one_at_bit(31) : bits::one_at_bit(27);
|
bits::is64() ? bits::one_at_bit(31) : bits::one_at_bit(27);
|
||||||
|
|
||||||
|
#ifdef SNMALLOC_CHECK_CLIENT
|
||||||
|
auto prot = PROT_NONE;
|
||||||
|
#else
|
||||||
|
auto prot = PROT_READ | PROT_WRITE;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (size_t size_request = bits::max(size, min_size);
|
for (size_t size_request = bits::max(size, min_size);
|
||||||
size_request >= size;
|
size_request >= size;
|
||||||
size_request = size_request / 2)
|
size_request = size_request / 2)
|
||||||
@@ -267,7 +275,7 @@ namespace snmalloc
|
|||||||
void* p = mmap(
|
void* p = mmap(
|
||||||
nullptr,
|
nullptr,
|
||||||
size_request,
|
size_request,
|
||||||
PROT_READ | PROT_WRITE,
|
prot,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | DefaultMMAPFlags<OS>::flags,
|
MAP_PRIVATE | MAP_ANONYMOUS | DefaultMMAPFlags<OS>::flags,
|
||||||
AnonFD<OS>::fd,
|
AnonFD<OS>::fd,
|
||||||
0);
|
0);
|
||||||
|
|||||||
Reference in New Issue
Block a user