1// commit: 3e936ce81bbbcc968f576aedbd5203621839f152 2014-09-19 2// flockfile linked list handling was broken 3#include <errno.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include "test.h" 8 9#define t_fatal(...) (t_error(__VA_ARGS__), _Exit(t_status)) 10#define length(a) (sizeof(a)/sizeof*(a)) 11 12// interpose malloc functions 13// freed memory is not reused, it is checked for clobber. 14 15static unsigned char buf[1<<20]; 16static size_t pos; 17static struct { 18 size_t pos; 19 size_t n; 20 int freed; 21} alloc[100]; 22static int idx; 23 24void *malloc(size_t n) 25{ 26 if (n == 0) n++; 27 if (n > sizeof buf - pos) 28 t_fatal("test buffer is small, pos: %zu, need: %zu\n", pos, n); 29 if (idx >= length(alloc)) 30 t_fatal("test buffer is small, idx: %d\n", idx); 31 void *p = buf + pos; 32 alloc[idx].pos = pos; 33 alloc[idx].n = n; 34 pos += n; 35 idx++; 36 return p; 37} 38 39void *calloc(size_t n, size_t m) 40{ 41 return memset(malloc(n*m), 0, n*m); 42} 43 44void *aligned_alloc(size_t a, size_t n) 45{ 46 t_fatal("aligned_alloc is unsupported\n"); 47} 48 49static int findidx(void *p) 50{ 51 size_t pos = (unsigned char *)p - buf; 52 for (int i=0; i<idx; i++) 53 if (alloc[i].pos == pos) 54 return i; 55 t_fatal("%p is not an allocated pointer\n", p); 56 return -1; 57} 58 59void *realloc(void *p, size_t n) 60{ 61 void *q = malloc(n); 62 size_t m = alloc[findidx(p)].n; 63 memcpy(q, p, m < n ? m : n); 64 free(p); 65 return q; 66} 67 68void free(void *p) 69{ 70 if (p == 0) return; 71 int i = findidx(p); 72 memset(p, 42, alloc[i].n); 73 alloc[i].freed = 1; 74} 75 76static void checkfreed(void) 77{ 78 for (int i=0; i<idx; i++) 79 if (alloc[i].freed) 80 for (size_t j=0; j<alloc[i].n; j++) 81 if (buf[alloc[i].pos + j] != 42) { 82 t_error("freed allocation %d (pos: %zu, len: %zu) is clobbered\n", i, alloc[i].pos, alloc[i].n); 83 break; 84 } 85} 86 87int main() 88{ 89 FILE *f = tmpfile(); 90 FILE *g = tmpfile(); 91 flockfile(g); 92 flockfile(f); 93 funlockfile(g); 94 fclose(g); 95 /* may corrupt memory */ 96 funlockfile(f); 97 checkfreed(); 98 return t_status; 99} 100