• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 static unsigned char buf[1<<20];
16 static size_t pos;
17 static struct {
18 	size_t pos;
19 	size_t n;
20 	int freed;
21 } alloc[100];
22 static int idx;
23 
malloc(size_t n)24 void *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 
calloc(size_t n,size_t m)39 void *calloc(size_t n, size_t m)
40 {
41 	return memset(malloc(n*m), 0, n*m);
42 }
43 
aligned_alloc(size_t a,size_t n)44 void *aligned_alloc(size_t a, size_t n)
45 {
46 	t_fatal("aligned_alloc is unsupported\n");
47 }
48 
findidx(void * p)49 static 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 
realloc(void * p,size_t n)59 void *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 
free(void * p)68 void 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 
checkfreed(void)76 static 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 
main()87 int 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