aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--chattymalloc.c118
2 files changed, 124 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index c7da232..05e04da 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,12 @@ MAKEFILE_LIST = Makefile
TARGETS = $(OBJPRE:.o=)
-all: $(TARGETS)
+all: $(TARGETS) $(OBJDIR)/chattymalloc.so
+
+$(OBJDIR)/chattymalloc.so: chattymalloc.c $(MAKEFILE_LIST)
+ @echo "cc $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CC) -shared $(CFLAGS) -o $@ $< -ldl
$(OBJDIR)/cache-thrash: $(OBJDIR)/cache-thrash.o
@echo "ld $@"
diff --git a/chattymalloc.c b/chattymalloc.c
new file mode 100644
index 0000000..db8d2de
--- /dev/null
+++ b/chattymalloc.c
@@ -0,0 +1,118 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char tmpbuff[1024];
+unsigned long tmppos = 0;
+unsigned long tmpallocs = 0;
+
+void *memset(void*,int,size_t);
+void *memmove(void *to, const void *from, size_t size);
+
+/*=========================================================
+ * * interception points
+ * */
+
+static void * (*myfn_calloc)(size_t nmemb, size_t size);
+static void * (*myfn_malloc)(size_t size);
+static void (*myfn_free)(void *ptr);
+static void * (*myfn_realloc)(void *ptr, size_t size);
+static void * (*myfn_memalign)(size_t blocksize, size_t bytes);
+
+static void init()
+{
+ myfn_malloc = dlsym(RTLD_NEXT, "malloc");
+ myfn_free = dlsym(RTLD_NEXT, "free");
+ myfn_calloc = dlsym(RTLD_NEXT, "calloc");
+ myfn_realloc = dlsym(RTLD_NEXT, "realloc");
+ myfn_memalign = dlsym(RTLD_NEXT, "memalign");
+
+ if (!myfn_malloc || !myfn_free || !myfn_calloc || !myfn_realloc || !myfn_memalign)
+ {
+ fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
+ exit(1);
+ }
+}
+
+void *malloc(size_t size)
+{
+ static int initializing = 0;
+ if (myfn_malloc == NULL)
+ {
+ if (!initializing)
+ {
+ initializing = 1;
+ init();
+ initializing = 0;
+
+ fprintf(stdout, "jcheck: allocated %lu bytes of temp memory in %lu chunks during initialization\n", tmppos, tmpallocs);
+ }
+ else
+ {
+ if (tmppos + size < sizeof(tmpbuff))
+ {
+ void *retptr = tmpbuff + tmppos;
+ tmppos += size;
+ ++tmpallocs;
+ return retptr;
+ }
+ else
+ {
+ fprintf(stdout, "jcheck: too much memory requested during initialisation - increase tmpbuff size\n");
+ exit(1);
+ }
+ }
+ }
+
+ fprintf(stderr, "%d\n", size);
+ void *ptr = myfn_malloc(size);
+ return ptr;
+}
+
+void free(void *ptr)
+{
+ // something wrong if we call free before one of the allocators!
+ if (myfn_malloc == NULL)
+ init();
+ if (ptr >= (void*) tmpbuff && ptr <= (void*)(tmpbuff + tmppos))
+ fprintf(stdout, "freeing temp memory\n");
+ else
+ myfn_free(ptr);
+}
+
+void *realloc(void *ptr, size_t size)
+{
+ if (myfn_malloc == NULL)
+ {
+ void *nptr = malloc(size);
+ if (nptr && ptr)
+ {
+ memmove(nptr, ptr, size);
+ free(ptr);
+ }
+ return nptr;
+ }
+ void *nptr = myfn_realloc(ptr, size);
+ return nptr;
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+ if (myfn_malloc == NULL)
+ {
+ void *ptr = malloc(nmemb*size);
+ if (ptr)
+ memset(ptr, 0, nmemb*size);
+ return ptr;
+ }
+ void *ptr = myfn_calloc(nmemb, size);
+ return ptr;
+}
+
+void *memalign(size_t blocksize, size_t bytes)
+{
+ void *ptr = myfn_memalign(blocksize, bytes);
+ return ptr;
+}