summaryrefslogtreecommitdiff
path: root/prism/internal/allocator_debug.h
diff options
context:
space:
mode:
Diffstat (limited to 'prism/internal/allocator_debug.h')
-rw-r--r--prism/internal/allocator_debug.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/prism/internal/allocator_debug.h b/prism/internal/allocator_debug.h
new file mode 100644
index 0000000000..846e96ba2d
--- /dev/null
+++ b/prism/internal/allocator_debug.h
@@ -0,0 +1,88 @@
+#ifndef PRISM_INTERNAL_ALLOCATOR_DEBUG_H
+#define PRISM_INTERNAL_ALLOCATOR_DEBUG_H
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static inline void *
+pm_allocator_debug_malloc(size_t size) {
+ size_t *memory = xmalloc(size + sizeof(size_t));
+ memory[0] = size;
+ return memory + 1;
+}
+
+static inline void *
+pm_allocator_debug_calloc(size_t nmemb, size_t size) {
+ size_t total_size = nmemb * size;
+ void *ptr = pm_allocator_debug_malloc(total_size);
+ memset(ptr, 0, total_size);
+ return ptr;
+}
+
+static inline void *
+pm_allocator_debug_realloc(void *ptr, size_t size) {
+ if (ptr == NULL) {
+ return pm_allocator_debug_malloc(size);
+ }
+
+ size_t *memory = (size_t *)ptr;
+ void *raw_memory = memory - 1;
+ memory = (size_t *)xrealloc(raw_memory, size + sizeof(size_t));
+ memory[0] = size;
+ return memory + 1;
+}
+
+static inline void
+pm_allocator_debug_free(void *ptr) {
+ if (ptr != NULL) {
+ size_t *memory = (size_t *)ptr;
+ xfree(memory - 1);
+ }
+}
+
+static inline void
+pm_allocator_debug_free_sized(void *ptr, size_t old_size) {
+ if (ptr != NULL) {
+ size_t *memory = (size_t *)ptr;
+ if (old_size != memory[-1]) {
+ fprintf(stderr, "[BUG] buffer %p was allocated with size %lu but freed with size %lu\n", ptr, memory[-1], old_size);
+ abort();
+ }
+ xfree_sized(memory - 1, old_size + sizeof(size_t));
+ }
+}
+
+static inline void *
+pm_allocator_debug_realloc_sized(void *ptr, size_t size, size_t old_size) {
+ if (ptr == NULL) {
+ if (old_size != 0) {
+ fprintf(stderr, "[BUG] realloc_sized called with NULL pointer and old size %lu\n", old_size);
+ abort();
+ }
+ return pm_allocator_debug_malloc(size);
+ }
+
+ size_t *memory = (size_t *)ptr;
+ if (old_size != memory[-1]) {
+ fprintf(stderr, "[BUG] buffer %p was allocated with size %lu but realloced with size %lu\n", ptr, memory[-1], old_size);
+ abort();
+ }
+ return pm_allocator_debug_realloc(ptr, size);
+}
+
+#undef xmalloc
+#undef xrealloc
+#undef xcalloc
+#undef xfree
+#undef xrealloc_sized
+#undef xfree_sized
+
+#define xmalloc pm_allocator_debug_malloc
+#define xrealloc pm_allocator_debug_realloc
+#define xcalloc pm_allocator_debug_calloc
+#define xfree pm_allocator_debug_free
+#define xrealloc_sized pm_allocator_debug_realloc_sized
+#define xfree_sized pm_allocator_debug_free_sized
+
+#endif