-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathmalloc_debug.c
114 lines (110 loc) · 2.63 KB
/
malloc_debug.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
This is a thin layer based on malloc/free. It checks for
(1) freeing a bloack that wasn't allocated with this utility
(2) Freeing twice a block
(3) Freeing a block that contains a memory overwrite past its allocated limit
Besides this, it contains an API for finding out the size of a block
Block layout:
|----------|-----------|--------------- ... ------------------|-------|
|Signature | Size | user memory of requested size | MAGIC |
+----------+-----------+--------------------------------------+-------|
lower addresses higher addresses
*/
#include "containers.h"
#define SIGNATURE 0xdeadbeef
#define MAGIC 0xbeefdead
static size_t AllocatedMemory;
#define ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
#define ALIGN_DEFAULT(size) ALIGN(size,sizeof(size_t))
static void *Malloc(size_t size)
{
register char *r;
register size_t *ip = NULL;
size = ALIGN_DEFAULT(size);
size += 3 * sizeof(size_t);
r = malloc(size);
if (r == NULL)
return NULL;
AllocatedMemory += size;
ip = (size_t *) r;
*ip++ = SIGNATURE;
*ip++ = size;
memset(ip, 0, size - 3*sizeof(size_t));
ip = (size_t *) (&r[size - sizeof(size_t)]);
*ip = MAGIC;
return (r + 2 * sizeof(size_t));
}
static void Free(void *pp)
{
size_t *ip = NULL;
size_t s;
register char *p = pp;
if (p == NULL)
return;
p -= 2 * sizeof(size_t);
ip = (size_t *) p;
if (*ip == SIGNATURE) {
*ip++ = 0;
s = *ip;
ip = (size_t *) (&p[s - sizeof(size_t)]);
if (*ip != MAGIC) {
/* overwritten block size %d\n */
iError.RaiseError("Free",CONTAINER_ERROR_BUFFEROVERFLOW);
return;
}
*ip = 0;
AllocatedMemory -= s;
memset(p,66,s);
free(p);
}
else {
/* Wrong block passed to Free */
iError.RaiseError("Free",CONTAINER_ERROR_BADPOINTER);
}
}
static void *Realloc(void *ptr,size_t newsize)
{
size_t oldsize;
size_t *ip;
void *result;
if (ptr == NULL)
return Malloc(newsize);
ip = ptr;
oldsize = *--ip;
if (*--ip != SIGNATURE) {
/* Wrong block passed to Free */
iError.RaiseError("Realloc",CONTAINER_ERROR_BADPOINTER);
return NULL;
}
newsize = ALIGN_DEFAULT(newsize);
oldsize -= 3*sizeof(size_t);
if (oldsize == newsize)
return ptr;
ip++;
if (newsize < oldsize) {
char *p;
*ip++ = newsize;
p = (char *)ip;
p += newsize - sizeof(size_t);
ip = (size_t *)p;
*ip = MAGIC;
return ptr;
}
result = Malloc(newsize);
if (result) {
memcpy(result,ptr,oldsize);
Free(ptr);
}
return result;
}
static void *Calloc(size_t n,size_t siz)
{
size_t totalSize = n * siz;
return Malloc(totalSize);
}
ContainerAllocator iDebugMalloc = {
Malloc,
Free,
Realloc,
Calloc,
};