From 7a51a35b815806db0272c4176286cd8185d32eae Mon Sep 17 00:00:00 2001 From: Anastasia Lyupa Date: Mon, 8 Jul 2013 11:19:50 +0400 Subject: [PATCH] use patch from d.bogatov: rewrite mem managing with glibc hooks --- custom_chart/da_chart.c | 3 + probe_memory/libdamemalloc.c | 132 ++++++++++++++++++++++--------------------- 2 files changed, 72 insertions(+), 63 deletions(-) diff --git a/custom_chart/da_chart.c b/custom_chart/da_chart.c index f0e9858..bbff716 100755 --- a/custom_chart/da_chart.c +++ b/custom_chart/da_chart.c @@ -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(); diff --git a/probe_memory/libdamemalloc.c b/probe_memory/libdamemalloc.c index 92d0fcd..2679cc3 100755 --- a/probe_memory/libdamemalloc.c +++ b/probe_memory/libdamemalloc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "daprobe.h" #include "probeinfo.h" #include "dacollection.h" @@ -42,24 +43,48 @@ #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; } -- 2.7.4