-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdmalloc.c
More file actions
111 lines (85 loc) · 2.39 KB
/
Copy pathdmalloc.c
File metadata and controls
111 lines (85 loc) · 2.39 KB
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
#define DMALLOC_DISABLE 1
#include "dmalloc.h"
#define BOUNDARY_SZ 4
#define TRAILER_MAGIC 0xAD
typedef struct metadata metadata_t;
struct metadata {
size_t sz;
uintptr_t alloced;
metadata_t *next, *prev;
};
static int disabled;
static bst_t* frees;
static hashtree_t* allocs;
static void init_base_alloc();
static void base_allocator_atexit();
void* dmalloc(size_t sz, const char* file, size_t line){
if (sz == 0)
return NULL;
if (disabled){
return malloc(sz);
}
++disabled;
init_base_alloc();
void* ptr = bst_fetch(frees, sz);
if (!ptr) {
ptr = malloc(sz+BOUNDARY_SZ);
}
if (!ptr) {
fprintf(stderr, "ERROR: failed to allocate %s:%zu, size %zu\n", file, line, sz);
exit(EXIT_FAILURE);
}
if (ptr) {
*((char*)ptr+sz) = TRAILER_MAGIC;
val_t v = {(uintptr_t)ptr, sz};
ht_ins(allocs, v, file, line);
}
--disabled;
return ptr;
}
void dfree(void* ptr, const char* file, size_t line){
if (disabled || !ptr){
free(ptr);
} else {
++disabled;
hashtree_t* ht = ht_get(allocs, (uintptr_t)ptr);
if (!ht){
fprintf(stderr, "ERROR: wild free, %p, %s:%zu\n", ptr, file, line);
exit(EXIT_FAILURE);
}
size_t sz = ht->val.sz;
bst_ins(frees, ht->val);
ht_del(allocs, ht->val);
--disabled;
uint8_t boundary = *( (uint8_t*)ptr + sz);
if (boundary != TRAILER_MAGIC){
fprintf(stderr, "ERROR: write past end of allocation for pointer %p at address %p, %s:%zu\n",
ptr, (char*)ptr+sz, file, line);
exit(EXIT_FAILURE);
}
}
}
void* dcalloc(size_t nmemb, size_t sz, const char* file, size_t line){
if (((size_t)-1)/nmemb <= sz){
fprintf(stderr, "ERROR: failed to allocate %s, %zu, count %zu of size %zu\n", file, line, nmemb, sz);
exit(EXIT_FAILURE);
}
void* ptr = dmalloc(nmemb * sz, file, line);
if (ptr){
memset(ptr, 0, nmemb * sz);
}
return ptr;
}
static void init_base_alloc(){
static int base_alloc_atexit_installed = 0;
if (!base_alloc_atexit_installed){
atexit(base_allocator_atexit);
frees = bst_init();
allocs = ht_init();
base_alloc_atexit_installed = 1;
}
}
static void base_allocator_atexit() {
ht_mem_leak_report(allocs);
bst_free(frees);
}