summaryrefslogtreecommitdiffstats
path: root/src/malloc-hook.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/malloc-hook.c')
-rw-r--r--src/malloc-hook.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/malloc-hook.c b/src/malloc-hook.c
new file mode 100644
index 0000000..b455b82
--- /dev/null
+++ b/src/malloc-hook.c
@@ -0,0 +1,74 @@
+
+#include <stdlib.h>
+
+static __thread int in_hook = 0;
+
+extern void (*__free_hook)(void *ptr);
+extern void *(*__malloc_hook)(size_t size);
+extern void *(*__realloc_hook)(void *ptr, size_t size);
+extern void *(*__memalign_hook)(size_t alignment, size_t size);
+
+void (*hook_free_saved)(void *ptr);
+void *(*hook_malloc_saved)(size_t size);
+void *(*hook_realloc_saved)(void *ptr, size_t size);
+void *(*hook_memalign_saved)(size_t alignment, size_t size);
+
+static int hooked_free;
+static int hooked_malloc;
+static int hooked_realloc;
+static int hooked_memalign;
+
+static void hook_free(void *ptr)
+{
+ in_hook = 1;
+ hook_free_saved(ptr);
+ in_hook = 0;
+}
+
+static void *hook_malloc(size_t size)
+{
+ void *p;
+
+ in_hook = 1;
+ p = hook_malloc_saved(size);
+ in_hook = 0;
+ return p;
+}
+
+static void *hook_realloc(void *ptr, size_t size)
+{
+ void *p;
+
+ in_hook = 1;
+ p = hook_realloc_saved(ptr, size);
+ in_hook = 0;
+ return p;
+}
+
+static void *hook_memalign(size_t alignment, size_t size)
+{
+ void *p;
+
+ in_hook = 1;
+ p = hook_memalign_saved(alignment, size);
+ in_hook = 0;
+ return p;
+}
+
+#define HOOK(name) \
+do { \
+ if (!hooked_##name && __##name##_hook) { \
+ hook_##name##_saved = __##name##_hook; \
+ __##name##_hook = hook_##name; \
+ hooked_##name = 1; \
+ } \
+} while(0)
+
+int check_malloc_hook(void)
+{
+ HOOK(free);
+ HOOK(malloc);
+ HOOK(realloc);
+ HOOK(memalign);
+ return in_hook ? -1 : 0;
+}