Caveat: This uses an array from a malloc
, so technically, it's not quite the same.
But, this will add a "guard" page/area at the end, which always causes a segfault.
I've often used this to debug "off-by-one" array indexing. I've found it to be so useful, that I've added it as part of a malloc
wrapper in my production code.
So, if the intent is to come up with something that debugs a real problem, this may help:
// segvforce -- force a segfault on going over bounds
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
// number of guard pages that follow
// NOTE: for simple increments, one is usually sufficient, but for larger
// increments or more complex indexing, choose a larger value
#ifndef GUARDCNT
#define GUARDCNT 1
#endif
#define GUARDSIZE (PAGESIZE * GUARDCNT)
// crash_alloc -- allocate for overbound protection
void *
crash_alloc(size_t curlen)
{
size_t pagelen;
void *base;
void *endp;
pagelen = curlen;
// align up to page size
pagelen += PAGESIZE - 1;
pagelen /= PAGESIZE;
pagelen *= PAGESIZE;
// add space for guard pages
pagelen += GUARDSIZE * 2;
base = NULL;
posix_memalign(&base,PAGESIZE,pagelen);
printf("base: %p\n",base);
// point to end of area
endp = base + pagelen;
printf("endp: %p\n",endp);
// back up to guard page and protect it
endp -= GUARDSIZE;
printf("prot: %p\n",endp);
mprotect(endp,GUARDSIZE,PROT_NONE);
// point to area for caller
endp -= curlen;
printf("fini: %p\n",endp);
return endp;
}
// main -- main program
int
main(int argc,char **argv)
{
int n;
int *arr;
int idx;
int val;
n = 3;
arr = crash_alloc(sizeof(int) * n);
val = 0;
for (idx = 0; idx <= n; ++idx) {
printf("try: %d\n",idx);
val += arr[idx];
}
printf("finish\n");
return val;
}