2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
18 # define PAGE_SIZE 4096
22 static const size_t kMapChunkSize
= 4 * PAGE_SIZE
;
23 static const size_t kTestSize
= 256 * PAGE_SIZE
;
25 static int64_t sHandledSignals
= 0;
27 static uint8_t* sMappedBase
;
28 static size_t sMappedSize
;
29 static uint8_t* sTouchedAddress
;
33 signal_handler(int signal
)
37 //printf("SIGSEGV at %p\n", sTouchedAddress);
39 // protect the last page of the current allocation writable
40 if (mprotect(sMappedBase
+ sMappedSize
- PAGE_SIZE
, PAGE_SIZE
,
41 PROT_READ
| PROT_WRITE
) < 0) {
42 fprintf(stderr
, "SIGSEGV: mprotect() failed: %s\n", strerror(errno
));
46 // allocate the next chunk
47 void* mappedAddress
= mmap(sMappedBase
+ sMappedSize
, kMapChunkSize
,
48 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_FIXED
, -1, 0);
49 if (mappedAddress
== MAP_FAILED
) {
50 fprintf(stderr
, "SIGSEGV: mmap() failed: %s\n", strerror(errno
));
54 printf("mapped %d bytes at %p\n", (int)kMapChunkSize
, mappedAddress
);
56 sMappedSize
+= kMapChunkSize
;
58 // map the last page read-only
59 if (mprotect(sMappedBase
+ sMappedSize
- PAGE_SIZE
, PAGE_SIZE
, PROT_READ
)
61 fprintf(stderr
, "SIGSEGV: mprotect() failed: %s\n", strerror(errno
));
70 // install signal handler
71 if (signal(SIGSEGV
, signal_handler
) == SIG_ERR
) {
72 fprintf(stderr
, "Error: Failed to install signal handler: %s\n",
77 // Map the complete test size plus one chunk and unmap all but the first
78 // chunk again, so no other memory gets into the way, when we mmap() the
79 // other chunks with MAP_FIXED.
80 sMappedBase
= (uint8_t*)mmap(NULL
, kTestSize
+ kMapChunkSize
,
81 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
82 if (sMappedBase
== MAP_FAILED
) {
83 fprintf(stderr
, "mmap() failed: %s\n", strerror(errno
));
86 munmap(sMappedBase
+ kMapChunkSize
, kTestSize
);
88 sMappedSize
= kMapChunkSize
;
90 printf("mapped %d bytes at %p\n", (int)sMappedSize
, sMappedBase
);
92 if (mprotect(sMappedBase
+ sMappedSize
- PAGE_SIZE
, PAGE_SIZE
, PROT_READ
)
94 fprintf(stderr
, "mprotect() failed: %s\n", strerror(errno
));
98 for (int i
= 0; i
< 256 * PAGE_SIZE
; i
++) {
99 sTouchedAddress
= sMappedBase
+ i
;
100 *sTouchedAddress
= 1;
103 printf("test finished successfully!\n");