I tried this approach, separate areas are created for guard pages. This is probably bad because a lot of coroutines can be created.
Test code:
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <OS.h>
struct TryFrame {
sigjmp_buf context;
void *trapAdr;
};
static void SignalHandler(int signal, siginfo_t *signalInfo, ucontext_t *ctx, TryFrame *frame)
{
printf("Signal\n");
frame->trapAdr = signalInfo->si_addr;
siglongjmp(frame->context, 1);
}
int main()
{
size_t size = 16*1024*1024;
void *mem = mmap(0, size, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0);
printf("mem: %p\n", mem);
void *allocMem = mmap((void*)((int8*)mem + B_PAGE_SIZE), size - 2*B_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
printf("allocMem: %p\n", allocMem);
TryFrame frame = {0};
struct sigaction action = {0};
action.sa_handler = (__sighandler_t)SignalHandler;
action.sa_flags = SA_SIGINFO;
action.sa_userdata = &frame;
sigaction(SIGSEGV, &action, NULL);
if (sigsetjmp(frame.context, true) == 0) {
for (int8 *ptr = (int8*)mem + size/2; ; ptr--) {
*ptr = 0xcc;
}
} else {
printf("low: 0x%" B_PRIxADDR "\n", (int8*)frame.trapAdr - (int8*)mem);
}
if (sigsetjmp(frame.context, true) == 0) {
for (int8 *ptr = (int8*)mem + size/2; ; ptr++) {
*ptr = 0xcc;
}
} else {
printf("high: 0x%" B_PRIxADDR "\n", ((int8*)mem + size) - (int8*)frame.trapAdr);
}
printf("[WAIT]"); fgetc(stdin);
return 0;
}
list_area:
./MMapTest2 (team 56487)
ID name address size alloc. #-cow #-in #-out
------------------------------------------------------------------------------------
6051848 rld heap 0x46e32aa000 10000 d000 0 0 0
6051849 _rld_debug_ 0x70f71b5000 1000 1000 0 0 0
6051858 MMapTest2 mmap area 0x8046306000 1000 0 0 0 0
6051859 MMapTest2 mmap area 0x8046307000 ffe000 ffe000 0 0 0
6051860 MMapTest2 mmap area 0x8047305000 1000 0 0 0 0
6051850 MMapTest2_seg0ro 0xb156819000 1000 0 0 0 0
6051851 MMapTest2_seg1rw 0xb156a19000 1000 1000 0 0 0
6051846 runtime_loader_seg0ro 0xd440571000 21000 0 0 0 0
6051847 runtime_loader_seg1rw 0xd440791000 2000 2000 0 0 0
6051855 libgcc_s.so.1_seg0ro 0x13753b97000 16000 0 0 0 0
6051856 libgcc_s.so.1_seg1rw 0x13753dac000 1000 1000 0 0 0
6051852 libroot.so_seg0ro 0x141fdabc000 10d000 0 0 0 0
6051853 libroot.so_seg1rw 0x141fddc9000 e000 e000 0 0 0
6051854 libroot.so_seg2rw 0x141fddd7000 44000 6000 0 0 0
6051857 heap 0x10c4ebaa7000 50000 1b000 0 0 0
6051844 MMapTest2_56487_stack 0x7fd732900000 1006000 6000 0 0 0
6051843 user area 0x7ff38a47b000 4000 4000 0 0 0
6051845 commpage 0x7ffff5f4d000 8000 0 0 0 0