From adc2d256eb980e3c105e73d0afd58fcc19df2356 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Mon, 8 Mar 2010 12:35:52 -0300 Subject: [PATCH] dix: add memory allocation wrapping functions for profiling We are using ld's --wrap scheme. To put this in action, you should define compiler flags like "-Wl,--wrap,malloc -Wl,--wrap,realloc -Wl,--wrap,free" in configuration time. Signed-off-by: Tiago Vignatti --- There're other ways to bypass malloc/free (using __malloc_hook, dynamic linker's LD_PRELOAD mechanism, etc), but I found this the most convenient and easy to deal. I'm sure one would suggest something else... I faced a weird and nasty bug that doesn't let me to use ErrorF to print, segfaulting in some memcpy() function. So I had to almost copy and paste xorg_backtrace() here and use fprint instead. Sigh. dix/dixutils.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/dix.h | 5 ++++ 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/dix/dixutils.c b/dix/dixutils.c index 8278d44..49332df 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -882,3 +882,68 @@ InitCallbackManager(void) numCallbackListsToCleanup = 0; listsToCleanup = NULL; } + +/* + * Memory allocation wrapping functions using ld's --wrap scheme. + * + * To put this in action, you should define CFLAGS="-Wl,--wrap,malloc + * -Wl,--wrap,realloc -Wl,--wrap,free" in autoconf time. + */ +#include +#include + +void *__real_malloc(size_t size); +void *__real_realloc(void *ptr, size_t size); +void __real_free(void *ptr); + +static +void print_bt(void) +{ + void *array[64]; + const char *mod; + int size, i; + Dl_info info; + size = backtrace(array, 64); + for (i = 0; i < size; i++) { + dladdr(array[i], &info); + mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; + + /* try to cut off unuseful info */ + if (info.dli_saddr && !strstr(info.dli_sname, "__libc_") && + !strstr(info.dli_sname, "__wrap_malloc") && + !strstr(info.dli_sname, "__wrap_free")) + fprintf(stderr, "%d: %s (%s+0x%lx) [%p]\n", i, mod, + info.dli_sname, (long unsigned int)((char *) array[i] - + (char *) info.dli_saddr), array[i]); + } + fprintf(stderr, "\n"); + +} + +void *__wrap_malloc(size_t size) +{ + void *ptr = __real_malloc(size); + fprintf(stderr, "malloc(%d) = %p\n", size, ptr); + print_bt(); + + return ptr; +} + +void *__wrap_realloc(void *ptr, size_t size) +{ + void *_ptr = __real_realloc(ptr, size); + fprintf(stderr, "realloc(%d) = %p\n", size, _ptr); + print_bt(); + + return _ptr; +} + + +/* the wrapper for free() */ +void __wrap_free(void *ptr) +{ + fprintf(stderr, "free(%p)\n", ptr); + print_bt(); + + __real_free(ptr); +} diff --git a/include/dix.h b/include/dix.h index 6505fd0..7052307 100644 --- a/include/dix.h +++ b/include/dix.h @@ -622,4 +622,9 @@ extern _X_EXPORT ClientPtr LookupClient( XID id, ClientPtr client); +/* memory allocation wrapping functions */ +extern void *__wrap_malloc(size_t size); +extern void *__wrap_realloc(void *ptr, size_t size); +extern void __wrap_free(void *ptr); + #endif /* DIX_H */ -- 1.6.3.3