Add trace support for calloc and realloc.
authorStefan Seefeld <stefan_seefeld@mentor.com>
Wed, 7 Aug 2013 15:28:12 +0000 (11:28 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 7 Aug 2013 15:28:12 +0000 (11:28 -0400)
Signed-off-by: Stefan Seefeld <stefan_seefeld@mentor.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust-libc-wrapper/lttng-ust-malloc.c
liblttng-ust-libc-wrapper/ust_libc.h

index 3212ff0bacca50f7e8511977ce66b708113f3c81..c7f747bdce5acb30fc6c13a276abdb643844d374 100644 (file)
 #include <dlfcn.h>
 #include <sys/types.h>
 #include <stdio.h>
+#include <pthread.h>
 
 #define TRACEPOINT_DEFINE
 #define TRACEPOINT_CREATE_PROBES
 #include "ust_libc.h"
 
+#define STATIC_CALLOC_LEN 4096
+static char static_calloc_buf[STATIC_CALLOC_LEN];
+static size_t static_calloc_buf_offset;
+static pthread_mutex_t static_calloc_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void *static_calloc(size_t nmemb, size_t size)
+{
+       size_t prev_offset;
+
+       pthread_mutex_lock(&static_calloc_mutex);
+       if (nmemb * size > sizeof(static_calloc_buf) - static_calloc_buf_offset) {
+               pthread_mutex_unlock(&static_calloc_mutex);
+               return NULL;
+       }
+       prev_offset = static_calloc_buf_offset;
+       static_calloc_buf_offset += nmemb * size;
+       pthread_mutex_unlock(&static_calloc_mutex);
+       return &static_calloc_buf[prev_offset];
+}
+
 void *malloc(size_t size)
 {
-       static void *(*plibc_malloc)(size_t size) = NULL;
+       static void *(*plibc_malloc)(size_t size);
        void *retval;
 
        if (plibc_malloc == NULL) {
@@ -45,7 +66,16 @@ void *malloc(size_t size)
 
 void free(void *ptr)
 {
-       static void *(*plibc_free)(void *ptr) = NULL;
+       static void (*plibc_free)(void *ptr);
+
+       /* Check whether the memory was allocated with
+        * static_calloc, in which case there is nothing
+        * to free.
+        */
+       if ((char *)ptr >= static_calloc_buf &&
+           (char *)ptr < static_calloc_buf + STATIC_CALLOC_LEN) {
+               return;
+       }
 
        if (plibc_free == NULL) {
                plibc_free = dlsym(RTLD_NEXT, "free");
@@ -57,3 +87,42 @@ void free(void *ptr)
        tracepoint(ust_libc, free, ptr);
        plibc_free(ptr);
 }
+
+void *calloc(size_t nmemb, size_t size)
+{
+       static void *(*volatile plibc_calloc)(size_t nmemb, size_t size);
+       void *retval;
+
+       if (plibc_calloc == NULL) {
+               /*
+                * Temporarily redirect to static_calloc,
+                * until the dlsym lookup has completed.
+                */
+               plibc_calloc = static_calloc;
+               plibc_calloc = dlsym(RTLD_NEXT, "calloc");
+               if (plibc_calloc == NULL) {
+                       fprintf(stderr, "callocwrap: unable to find calloc\n");
+                       return NULL;
+               }
+       }
+       retval = plibc_calloc(nmemb, size);
+       tracepoint(ust_libc, calloc, nmemb, size, retval);
+       return retval;
+}
+
+void *realloc(void *ptr, size_t size)
+{
+       static void *(*plibc_realloc)(void *ptr, size_t size);
+       void *retval;
+
+       if (plibc_realloc == NULL) {
+               plibc_realloc = dlsym(RTLD_NEXT, "realloc");
+               if (plibc_realloc == NULL) {
+                       fprintf(stderr, "reallocwrap: unable to find realloc\n");
+                       return NULL;
+               }
+       }
+       retval = plibc_realloc(ptr, size);
+       tracepoint(ust_libc, realloc, ptr, size, retval);
+       return retval;
+}
index af705aac2a4483695b55fd1e086d90fdfb7a202e..d2096a3aa43667de90ecfc43f0c49632096bc173 100644 (file)
@@ -36,14 +36,32 @@ TRACEPOINT_EVENT(ust_libc, malloc,
        TP_ARGS(size_t, size, void *, ptr),
        TP_FIELDS(
                ctf_integer(size_t, size, size)
-               ctf_integer_hex(unsigned long, ptr, (unsigned long) ptr)
+               ctf_integer_hex(void *, ptr, ptr)
        )
 )
 
 TRACEPOINT_EVENT(ust_libc, free,
        TP_ARGS(void *, ptr),
        TP_FIELDS(
-               ctf_integer_hex(unsigned long, ptr, (unsigned long) ptr)
+               ctf_integer_hex(void *, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(ust_libc, calloc,
+       TP_ARGS(size_t, nmemb, size_t, size, void *, ptr),
+       TP_FIELDS(
+               ctf_integer(size_t, nmemb, nmemb)
+               ctf_integer(size_t, size, size)
+               ctf_integer_hex(void *, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(ust_libc, realloc,
+       TP_ARGS(void *, in_ptr, size_t, size, void *, ptr),
+       TP_FIELDS(
+               ctf_integer_hex(void *, in_ptr, in_ptr)
+               ctf_integer(size_t, size, size)
+               ctf_integer_hex(void *, ptr, ptr)
        )
 )
 
This page took 0.026264 seconds and 4 git commands to generate.