Skip to content

Commit d1c9f9b

Browse files
committed
Introduce xfree_sized and xrealloc_sized
1 parent 62c7300 commit d1c9f9b

2 files changed

Lines changed: 127 additions & 4 deletions

File tree

include/prism/debug_allocator.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* @file debug_allocator.h
3+
*
4+
* Decorate allocation function to ensure sizes are correct.
5+
*/
6+
#ifndef PRISM_DEBUG_ALLOCATOR_H
7+
#define PRISM_DEBUG_ALLOCATOR_H
8+
9+
#include <string.h>
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
13+
static inline void *
14+
pm_debug_malloc(size_t size)
15+
{
16+
size_t *memory = xmalloc(size + sizeof(size_t));
17+
memory[0] = size;
18+
return memory + 1;
19+
}
20+
21+
static inline void *
22+
pm_debug_calloc(size_t nmemb, size_t size)
23+
{
24+
size_t total_size = nmemb * size;
25+
void *ptr = pm_debug_malloc(total_size);
26+
memset(ptr, 0, total_size);
27+
return ptr;
28+
}
29+
30+
static inline void *
31+
pm_debug_realloc(void *ptr, size_t size)
32+
{
33+
if (ptr == NULL) {
34+
return pm_debug_malloc(size);
35+
}
36+
37+
size_t *memory = (size_t *)ptr;
38+
void *raw_memory = memory - 1;
39+
memory = (size_t *)xrealloc(raw_memory, size + sizeof(size_t));
40+
memory[0] = size;
41+
return memory + 1;
42+
}
43+
44+
static inline void
45+
pm_debug_free(void *ptr)
46+
{
47+
if (ptr != NULL) {
48+
size_t *memory = (size_t *)ptr;
49+
xfree(memory - 1);
50+
}
51+
}
52+
53+
static inline void
54+
pm_debug_free_sized(void *ptr, size_t old_size)
55+
{
56+
if (ptr != NULL) {
57+
size_t *memory = (size_t *)ptr;
58+
if (old_size != memory[-1]) {
59+
fprintf(stderr, "[BUG] buffer %p was allocated with size %lu but freed with size %lu\n", ptr, memory[-1], old_size);
60+
abort();
61+
}
62+
xfree_sized(memory - 1, old_size + sizeof(size_t));
63+
}
64+
}
65+
66+
static inline void *
67+
pm_debug_realloc_sized(void *ptr, size_t size, size_t old_size)
68+
{
69+
if (ptr == NULL) {
70+
if (old_size != 0) {
71+
fprintf(stderr, "[BUG] realloc_sized called with NULL pointer and old size %lu\n", old_size);
72+
abort();
73+
}
74+
return pm_debug_malloc(size);
75+
}
76+
77+
size_t *memory = (size_t *)ptr;
78+
if (old_size != memory[-1]) {
79+
fprintf(stderr, "[BUG] buffer %p was allocated with size %lu but realloced with size %lu\n", ptr, memory[-1], old_size);
80+
abort();
81+
}
82+
return pm_debug_realloc(ptr, size);
83+
}
84+
85+
#undef xmalloc
86+
#undef xrealloc
87+
#undef xcalloc
88+
#undef xfree
89+
#undef xrealloc_sized
90+
#undef xfree_sized
91+
92+
#define xmalloc pm_debug_malloc
93+
#define xrealloc pm_debug_realloc
94+
#define xcalloc pm_debug_calloc
95+
#define xfree pm_debug_free
96+
#define xrealloc_sized pm_debug_realloc_sized
97+
#define xfree_sized pm_debug_free_sized
98+
99+
#endif

include/prism/defines.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,12 @@
161161
* ```
162162
* #ifndef PRISM_XALLOCATOR_H
163163
* #define PRISM_XALLOCATOR_H
164-
* #define xmalloc my_malloc
165-
* #define xrealloc my_realloc
166-
* #define xcalloc my_calloc
167-
* #define xfree my_free
164+
* #define xmalloc my_malloc
165+
* #define xrealloc my_realloc
166+
* #define xcalloc my_calloc
167+
* #define xfree my_free
168+
* #define xrealloc_sized my_realloc_sized // (optional)
169+
* #define xfree_sized my_free_sized // (optional)
168170
* #endif
169171
* ```
170172
*/
@@ -204,6 +206,28 @@
204206
#endif
205207
#endif
206208

209+
#ifndef xfree_sized
210+
/**
211+
* The free_sized function that should be used. This can be overridden with the
212+
* PRISM_XALLOCATOR define.
213+
* If not defined, defaults to calling xfree.
214+
*/
215+
#define xfree_sized(p, s) xfree(p)
216+
#endif
217+
218+
#ifndef xrealloc_sized
219+
/**
220+
* The xrealloc_sized function that should be used. This can be overridden with the
221+
* PRISM_XALLOCATOR define.
222+
* If not defined, defaults to calling xrealloc.
223+
*/
224+
#define xrealloc_sized(p, ns, os) xrealloc(p, ns)
225+
#endif
226+
227+
#ifdef PRISM_BUILD_DEBUG
228+
#include "prism/debug_allocator.h"
229+
#endif
230+
207231
/**
208232
* If PRISM_BUILD_MINIMAL is defined, then we're going to define every possible
209233
* switch that will turn off certain features of prism.

0 commit comments

Comments
 (0)