use patch from d.bogatov: rewrite mem managing with glibc hooks
authorAnastasia Lyupa <a.lyupa@samsung.com>
Mon, 8 Jul 2013 07:19:50 +0000 (11:19 +0400)
committerAnastasia Lyupa <a.lyupa@samsung.com>
Mon, 8 Jul 2013 07:19:50 +0000 (11:19 +0400)
custom_chart/da_chart.c
probe_memory/libdamemalloc.c

index f0e9858..bbff716 100755 (executable)
@@ -385,6 +385,9 @@ static void remove_from_callback_list(da_handle charthandle, da_handle series_ha
 // constructor and destructor functions
 // =====================================================================
 
+void memory_initialize_hook(void);
+void (*__malloc_initialize_hook) (void) = memory_initialize_hook;
+
 void __attribute__((constructor)) _init_lib()
 {
        probeBlockStart();
index 92d0fcd..2679cc3 100755 (executable)
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 #include <memory.h>
 #include <errno.h>
+#include <malloc.h>
 #include "daprobe.h"
 #include "probeinfo.h"
 #include "dacollection.h"
 #include "da_memory.h"
 #include "binproto.h"
 
-#define EXTRA_MEM_SIZE         20
 //#define INTERNALFILTERING            (!isEnableInternalMalloc())
 #define INTERNALFILTERING              true
-static char extra_mem[EXTRA_MEM_SIZE];
 static enum DaOptions _sopt = OPT_ALLOC;
 
-void *malloc(size_t size)
+static void* (*saved_malloc_hook)(size_t, const void*);
+static void* malloc_hook(size_t, const void*);
+static void* (*saved_realloc_hook)(void*, size_t, const void*);
+static void* realloc_hook(void*, size_t, const void*);
+static void (*saved_free_hook)(void*, const void*);
+static void free_hook(void*, const void*);
+
+static void install_memory_hooks()
+{
+  __malloc_hook = malloc_hook;
+  __realloc_hook = realloc_hook;
+  __free_hook = free_hook;
+}
+static void teardown_memory_hooks()
+{
+  __malloc_hook = saved_malloc_hook;
+  __realloc_hook = saved_realloc_hook;
+  __free_hook = saved_free_hook;
+}
+
+void memory_initialize_hook(void)
+{
+  saved_malloc_hook = __malloc_hook;
+  saved_realloc_hook = __realloc_hook;
+  saved_free_hook = __free_hook;
+  install_memory_hooks();
+}
+
+static void *malloc_hook(size_t size, const void* caller)
 {
-       static void*(*mallocp)(size_t size);
        DECLARE_VARIABLE_STANDARD;
        void *pret;
 
-       GET_REAL_FUNC_RTLD_NEXT(malloc);
-
+       teardown_memory_hooks();
        bfiltering = INTERNALFILTERING;
        PRE_PROBEBLOCK();
 
-       pret = mallocp(size);
+       pret = malloc(size);
 
        if(pret != NULL && getTraceState() == 0)
        {
@@ -76,15 +101,16 @@ void *malloc(size_t size)
        
        POST_PACK_PROBEBLOCK_END();
 
+       install_memory_hooks();
+
        return pret;
 }
 
-void free(void *ptr)
+static void free_hook(void *ptr, const void *caller)
 {
-       static void (*freep)(void *);
        DECLARE_VARIABLE_STANDARD;
 
-       GET_REAL_FUNC_RTLD_NEXT(free);
+       teardown_memory_hooks();
 
        bfiltering = INTERNALFILTERING;
        PRE_PROBEBLOCK();
@@ -94,7 +120,7 @@ void free(void *ptr)
                del_memory_hash(ptr);
        }
 
-       freep(ptr);
+       free(ptr);
 
        POST_PACK_PROBEBLOCK_BEGIN();
        
@@ -105,102 +131,82 @@ void free(void *ptr)
        FLUSH_LOCAL_BUF();
        
        POST_PACK_PROBEBLOCK_END();
-}
 
-/*     calloc's helper fucntion
- *     - dlsym calls calloc - recursion occurs
- *     - first dlsym calls temp_calloc
- *  */
-void *temp_calloc(size_t nelem, size_t elsize)
-{
-       int i;
-       if(nelem * elsize > EXTRA_MEM_SIZE)
-       {
-               // temp_calloc size error
-               abort();
-       }
-       for(i = 0; i < elsize * nelem; i++)
-       {
-               extra_mem[i] = 0;
-       }
-       //memset(extra_mem,0,elsize*nelem);
-       return extra_mem;
+       install_memory_hooks();
 }
 
-void *calloc(size_t nelem, size_t elsize)
+static void* realloc_hook(void *memblock, size_t size, const void* caller)
 {
-       static void *(*callocp)(size_t,size_t);
        DECLARE_VARIABLE_STANDARD;
        void *pret;
 
-       if(!callocp) {
-               probeBlockStart();
-               callocp = temp_calloc;  // make callocp is not null for dlsym
-               // dlsym use calloc function
-               callocp = dlsym(RTLD_NEXT, "calloc");
-               if(callocp == NULL || dlerror() != NULL) {
-                       perror("calloc dlsym failed");
-                       exit(0);
-               }
-               probeBlockEnd();
-       }
+       teardown_memory_hooks();
 
        bfiltering = INTERNALFILTERING;
        PRE_PROBEBLOCK();
 
-       pret = callocp(nelem, elsize);
+       if(memblock != NULL && getTraceState() == 0)
+       {
+               del_memory_hash(memblock);
+       }
+
+       pret = realloc(memblock, size);
 
        if(pret != NULL && getTraceState() == 0)
        {
-               add_memory_hash(pret, nelem * elsize);
+               add_memory_hash(pret, size);
        }
 
        POST_PACK_PROBEBLOCK_BEGIN();
        
        PREPARE_LOCAL_BUF();
-       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, LC_MEMORY, "xx", nelem, elsize);
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, LC_MEMORY, "px", memblock, size);
        PACK_COMMON_END(pret, newerrno, blockresult);
-       PACK_MEMORY(elsize, MEMORY_API_ALLOC, pret);
+       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
        FLUSH_LOCAL_BUF();
        
        POST_PACK_PROBEBLOCK_END();
 
+       install_memory_hooks();
+
        return pret;
 }
 
-void *realloc(void *memblock, size_t size)
+static inline void adhoc_bzero(char *p, size_t size)
+{
+       int index;
+       for (index = 0; index != size; index++)
+               p[index] = '\0';
+}
+
+void *calloc(size_t nelem, size_t elsize)
 {
-       static void *(*reallocp)(void *,size_t);
        DECLARE_VARIABLE_STANDARD;
        void *pret;
-
-       GET_REAL_FUNC_RTLD_NEXT(realloc);
-
+       size_t size = nelem * elsize;
        bfiltering = INTERNALFILTERING;
        PRE_PROBEBLOCK();
 
-       if(memblock != NULL && getTraceState() == 0)
-       {
-               del_memory_hash(memblock);
-       }
-
-       pret = reallocp(memblock, size);
+       pret = (size < elsize) ? NULL : malloc(size);
+       if (pret)
+                       adhoc_bzero(pret, nelem * elsize);
 
        if(pret != NULL && getTraceState() == 0)
        {
-               add_memory_hash(pret, size);
+               add_memory_hash(pret, nelem * elsize);
        }
 
        POST_PACK_PROBEBLOCK_BEGIN();
-       
+
        PREPARE_LOCAL_BUF();
-       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, LC_MEMORY, "px", memblock, size);
+       PACK_COMMON_BEGIN(MSG_PROBE_MEMORY, LC_MEMORY, "xx", nelem, elsize);
        PACK_COMMON_END(pret, newerrno, blockresult);
-       PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
+       PACK_MEMORY(nelem * elsize, MEMORY_API_ALLOC, pret);
        FLUSH_LOCAL_BUF();
-       
+
        POST_PACK_PROBEBLOCK_END();
 
+
        return pret;
 }