1 /* 2 Make sure that leak-check's pointer tracing avoids traps, i.e. tricky 3 memory areas where it could crash if not careful. 4 */ 5 6 #include <stdio.h> 7 #include "memcheck/memcheck.h" 8 #include "tests/sys_mman.h" 9 #include <stdlib.h> 10 #include <fcntl.h> 11 #include <unistd.h> 12 13 #if !defined(MAP_NORESERVE) 14 # define MAP_NORESERVE 0 15 #endif 16 17 int main() 18 { 19 char **volatile ptrs; 20 int i; 21 int fd; 22 char *map; 23 24 /* I _think_ the point of this is to fill ptrs with a pointer 25 to every 4th page in the entire address space, hence 26 guaranteeing that at least one of them points into one of 27 the below traps, and so checks that the leak checker 28 doesn't bomb when following them. That's fine on 32-bit 29 platforms, but hopeless for a 64-bit system. So the 30 following settings do achieve that on a 32-bit target but 31 merely make a 64-bit target give the same output without 32 properly testing it. */ 33 int ptrbits, stepbits, stepsize, nptrs; 34 if (sizeof(void*) == 8) { 35 /* 64-bit machine */ 36 ptrbits = 32; //bogus 37 stepbits = 14+1; //bogus 38 stepsize = (1 << stepbits); 39 nptrs = 1 << (ptrbits - stepbits); 40 } else { 41 /* 32-bit machine */ 42 ptrbits = 32; 43 stepbits = 14; 44 stepsize = (1 << stepbits); 45 nptrs = 1 << (ptrbits - stepbits); 46 } 47 48 ptrs = malloc(nptrs * sizeof(char *)); 49 for (i = 0; i < nptrs; i++) 50 ptrs[i] = (char *)((long)i << stepbits); 51 52 /* lay some traps */ 53 /* non-RWX memory, and MAP_NORESERVE if present */ 54 map = mmap(0, stepsize * 2, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); 55 if (map == (char *)-1) 56 perror("trap 1 failed"); 57 58 /* write-only memory, and MAP_NORESERVE if supported */ 59 map = mmap(0, stepsize * 2, PROT_WRITE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); 60 if (map == (char *)-1) 61 perror("trap 2 failed"); 62 63 /* non-zero mmap of a zero-length file -> SIGBUS */ 64 fd = open("./pointer-trace-test-file", O_RDWR | O_CREAT | O_EXCL, 0600); 65 unlink("./pointer-trace-test-file"); 66 map = mmap(0, stepsize * 2, PROT_WRITE|PROT_READ, MAP_PRIVATE, fd, 0); 67 if (map == (char *)-1) 68 perror("trap 3 failed"); 69 //printf("trap 3 = %p-%p\n", map, map+stepsize*2); 70 71 /* unmapped memory that's marked as defined */ 72 map = mmap(0, 256*1024, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); 73 if (map == (char *)-1) 74 perror("trap 4 failed"); 75 else { 76 munmap(map, 256*1024); 77 VALGRIND_MAKE_MEM_DEFINED(map, 256*1024); /* great big fat lie */ 78 } 79 80 VALGRIND_DO_LEAK_CHECK; 81 82 free(ptrs); 83 84 // We deliberately make a leak, it'll be obvious if something went 85 // wrong because the message won't be printed. 86 ptrs = malloc(1000); 87 88 return 0; 89 } 90