Handle calloc.
authorMilian Wolff <mail@milianw.de>
Thu, 15 May 2014 17:24:02 +0000 (19:24 +0200)
committerMilian Wolff <mail@milianw.de>
Thu, 15 May 2014 17:24:02 +0000 (19:24 +0200)
malloctrace.cpp
test.cpp

index 6ec6af4..f57a812 100644 (file)
@@ -35,10 +35,12 @@ namespace {
 using malloc_t = void* (*) (size_t);
 using free_t = void (*) (void*);
 using realloc_t = void* (*) (void*, size_t);
+using calloc_t = void* (*) (size_t, size_t);
 
 malloc_t real_malloc = nullptr;
 free_t real_free = nullptr;
 realloc_t real_realloc = nullptr;
+calloc_t real_calloc = nullptr;
 
 struct IPCacheEntry
 {
@@ -142,6 +144,28 @@ T findReal(const char* name)
     return reinterpret_cast<T>(ret);
 }
 
+/**
+ * Dummy implementation, since the call to dlsym from findReal triggers a call to calloc.
+ *
+ * This is only called at startup and will eventually be replaced by the "proper" calloc implementation.
+ */
+void* dummy_calloc(size_t num, size_t size)
+{
+    const size_t MAX_SIZE = 1024;
+    static char* buf[MAX_SIZE];
+    static size_t offset = 0;
+    if (!offset) {
+        memset(buf, 0, MAX_SIZE);
+    }
+    size_t oldOffset = offset;
+    offset += num * size;
+    if (offset >= MAX_SIZE) {
+        fprintf(stderr, "failed to initialize, dummy calloc buf size exhausted: %lu requested, %lu available\n", offset, MAX_SIZE);
+        exit(1);
+    }
+    return buf + oldOffset;
+}
+
 void init()
 {
     if (in_handler) {
@@ -151,6 +175,8 @@ void init()
 
     in_handler = true;
 
+    real_calloc = &dummy_calloc;
+    real_calloc = findReal<calloc_t>("calloc");
     real_malloc = findReal<malloc_t>("malloc");
     real_free = findReal<free_t>("free");
     real_realloc = findReal<realloc_t>("realloc");
@@ -174,7 +200,7 @@ void handleFree(void* ptr)
 
 extern "C" {
 
-/// TODO: calloc, memalign, ...
+/// TODO: memalign, ...
 
 void* malloc(size_t size)
 {
@@ -226,4 +252,21 @@ void* realloc(void* ptr, size_t size)
     return ret;
 }
 
+void* calloc(size_t num, size_t size)
+{
+    if (!real_calloc) {
+        init();
+    }
+
+    void* ret = real_calloc(num, size);
+
+    if (!in_handler) {
+        in_handler = true;
+        handleMalloc(ret, num*size);
+        in_handler = false;
+    }
+
+    return ret;
+}
+
 }
index 72af65c..a780c96 100644 (file)
--- a/test.cpp
+++ b/test.cpp
@@ -1,4 +1,5 @@
 #include <cstdlib>
+#include <cstdio>
 
 struct Foo {
     Foo()
@@ -16,13 +17,23 @@ static Foo foo;
 
 int main()
 {
-    char* c = new char[1000];
-    delete[] c;
     Foo* f = new Foo;
+    printf("new Foo: %p\n", f);
     delete f;
 
+    char* c = new char[1000];
+    printf("new char[]: %p\n", c);
+    delete[] c;
+
     void* buf = malloc(100);
+    printf("malloc: %p\n", buf);
     buf = realloc(buf, 200);
+    printf("realloc: %p\n", buf);
+    free(buf);
+
+    buf = calloc(5, 5);
+    printf("calloc: %p\n", buf);
     free(buf);
+
     return 0;
 }