5 #define REDZONE_SIZE 32
6 #define REDZONE_LEFT 0x78
7 #define REDZONE_RIGHT 0x87
12 LIST_ENTRY list_entry
;
15 } alloc_info
, *palloc_info
;
17 static size_t allocations
= 0;
18 static size_t allocated_memory
= 0;
19 static LIST_ENTRY alloc_list_head
= {&alloc_list_head
, &alloc_list_head
};
22 get_base_ptr(void *ptr
)
24 return (void *)((UINT_PTR
)ptr
- REDZONE_SIZE
- sizeof(alloc_info
));
28 get_ptr_from_base(palloc_info info
)
30 return (void*)((size_t)(info
+ 1) + REDZONE_SIZE
);
34 write_redzone(void *ptr
, size_t size
, const char *file
, int line
)
37 palloc_info info
= (palloc_info
)ptr
;
43 ptr
= (void *)(info
+ 1);
44 memset(ptr
, REDZONE_LEFT
, REDZONE_SIZE
);
45 ret
= (void *)((size_t)ptr
+ REDZONE_SIZE
);
46 ptr
= (void *)((size_t)ret
+ size
);
47 memset(ptr
, REDZONE_RIGHT
, REDZONE_SIZE
);
52 check_redzone_region(void *ptr
, unsigned char sig
, void **newptr
)
57 p
= (unsigned char *)ptr
;
71 redzone_err(const char *msg
, palloc_info info
, void *ptr
, const char *file
, int line
)
73 DbgPrint("CMD: %s\n", msg
);
74 DbgPrint(" Block: 0x%p Size: %lu\n", ptr
, info
->size
);
75 DbgPrint(" Allocated from %s:%d\n", info
->file
, info
->line
);
76 DbgPrint(" Detected at: %s:%d\n", file
, line
);
82 check_redzone(void *ptr
, const char *file
, int line
)
84 palloc_info info
= (palloc_info
)ptr
;
85 ptr
= (void *)(info
+ 1);
86 if (!check_redzone_region(ptr
, REDZONE_LEFT
, &ptr
))
87 redzone_err("Detected buffer underflow!", info
, ptr
, file
, line
);
88 ptr
= (void *)((UINT_PTR
)ptr
+ info
->size
);
89 if (!check_redzone_region(ptr
, REDZONE_RIGHT
, NULL
))
90 redzone_err("Detected buffer overflow!", info
, ptr
, file
, line
);
94 calculate_size_with_redzone(size_t size
)
96 return sizeof(alloc_info
) + size
+ (2 * REDZONE_SIZE
);
100 add_mem_to_list(void *ptr
)
102 palloc_info info
= (palloc_info
)ptr
;
103 InsertTailList(&alloc_list_head
, &info
->list_entry
);
107 del_mem_from_list(void *ptr
)
109 palloc_info info
= (palloc_info
)ptr
;
110 RemoveEntryList(&info
->list_entry
);
120 entry
= alloc_list_head
.Flink
;
121 while (entry
!= &alloc_list_head
)
123 info
= CONTAINING_RECORD(entry
, alloc_info
, list_entry
);
125 DbgPrint(" * Block: 0x%p Size: %lu allocated from %s:%d\n", get_ptr_from_base(info
), info
->size
, info
->file
, info
->line
);
127 ptr
= (void *)(info
+ 1);
128 if (!check_redzone_region(ptr
, REDZONE_LEFT
, &ptr
))
130 DbgPrint(" !!! Detected buffer underflow !!!\n");
133 ptr
= (void *)((UINT_PTR
)ptr
+ info
->size
);
134 if (!check_redzone_region(ptr
, REDZONE_RIGHT
, NULL
))
136 DbgPrint(" !!! Detected buffer overflow !!!\n");
139 entry
= entry
->Flink
;
144 cmd_alloc_dbg(size_t size
, const char *file
, int line
)
148 newptr
= malloc(calculate_size_with_redzone(size
));
152 allocated_memory
+= size
;
153 add_mem_to_list(newptr
);
154 newptr
= write_redzone(newptr
, size
, file
, line
);
161 cmd_realloc_dbg(void *ptr
, size_t size
, const char *file
, int line
)
167 return cmd_alloc_dbg(size
, file
, line
);
170 cmd_free_dbg(ptr
, file
, line
);
174 ptr
= get_base_ptr(ptr
);
175 prev_size
= ((palloc_info
)ptr
)->size
;
176 check_redzone(ptr
, file
, line
);
178 del_mem_from_list(ptr
);
179 newptr
= realloc(ptr
, calculate_size_with_redzone(size
));
182 allocated_memory
+= size
- prev_size
;
183 add_mem_to_list(newptr
);
184 newptr
= write_redzone(newptr
, size
, file
, line
);
187 add_mem_to_list(ptr
);
193 cmd_free_dbg(void *ptr
, const char *file
, int line
)
197 ptr
= get_base_ptr(ptr
);
198 check_redzone(ptr
, file
, line
);
200 allocated_memory
-= ((palloc_info
)ptr
)->size
;
201 del_mem_from_list(ptr
);
208 cmd_dup_dbg(const TCHAR
*str
, const char *file
, int line
)
214 ptr
= (TCHAR
*)cmd_alloc_dbg((_tcslen(str
) + 1) * sizeof(TCHAR
), file
, line
);
225 cmd_checkbuffer_dbg(void *ptr
, const char *file
, int line
)
229 ptr
= get_base_ptr(ptr
);
230 check_redzone(ptr
, file
, line
);
237 if (allocations
!= 0 || allocated_memory
!= 0)
239 DbgPrint("CMD: Leaking %lu bytes of memory in %lu blocks! Exit code: %d\n", allocated_memory
, allocations
, code
);
240 if (allocations
!= 0)