67 lines
2.1 KiB
C
67 lines
2.1 KiB
C
|
|
// tests/unit/madvise_guard_test.c - Box-level tests for madvise guard
|
||
|
|
#include <assert.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
#include <stdatomic.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <sys/mman.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
|
||
|
|
#include "box/madvise_guard_box.h"
|
||
|
|
#include "box/ss_os_acquire_box.h"
|
||
|
|
|
||
|
|
// Provide counter definitions for the guard (standalone unit test).
|
||
|
|
_Atomic uint64_t g_ss_mmap_count = 0;
|
||
|
|
_Atomic uint64_t g_final_fallback_mmap_count = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_alloc_calls = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_free_calls = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_madvise_calls = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_madvise_fail_enomem = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_madvise_fail_other = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_huge_alloc_calls = 0;
|
||
|
|
_Atomic uint64_t g_ss_os_huge_fail_calls = 0;
|
||
|
|
_Atomic bool g_ss_madvise_disabled = false;
|
||
|
|
|
||
|
|
static void reset_counters(void) {
|
||
|
|
atomic_store(&g_ss_os_madvise_calls, 0);
|
||
|
|
atomic_store(&g_ss_os_madvise_fail_enomem, 0);
|
||
|
|
atomic_store(&g_ss_os_madvise_fail_other, 0);
|
||
|
|
atomic_store(&g_ss_madvise_disabled, false);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void test_dso_pointer_is_skipped(void) {
|
||
|
|
reset_counters();
|
||
|
|
int ret = ss_os_madvise_guarded((void*)&ss_os_madvise_guarded, 4096, MADV_DONTNEED, "dso_skip");
|
||
|
|
if (ret != 0) {
|
||
|
|
fprintf(stderr, "madvise_guard returned %d for DSO pointer\n", ret);
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
assert(atomic_load(&g_ss_os_madvise_calls) == 0);
|
||
|
|
assert(!atomic_load(&g_ss_madvise_disabled));
|
||
|
|
}
|
||
|
|
|
||
|
|
static void test_anonymous_region_makes_syscall(void) {
|
||
|
|
reset_counters();
|
||
|
|
long page = sysconf(_SC_PAGESIZE);
|
||
|
|
if (page <= 0) page = 4096;
|
||
|
|
|
||
|
|
void* mem = mmap(NULL, (size_t)page, PROT_READ | PROT_WRITE,
|
||
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||
|
|
assert(mem && mem != MAP_FAILED);
|
||
|
|
|
||
|
|
int ret = ss_os_madvise_guarded(mem, (size_t)page, MADV_DONTNEED, "anon_region");
|
||
|
|
if (ret != 0) {
|
||
|
|
fprintf(stderr, "madvise_guard returned %d for anon region\n", ret);
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
assert(atomic_load(&g_ss_os_madvise_calls) == 1);
|
||
|
|
|
||
|
|
munmap(mem, (size_t)page);
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void) {
|
||
|
|
test_dso_pointer_is_skipped();
|
||
|
|
test_anonymous_region_makes_syscall();
|
||
|
|
return 0;
|
||
|
|
}
|