├── .gitignore ├── Makefile ├── README.md └── wrapalloc.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | *.swo 4 | *.o 5 | *.so 6 | reindex 7 | *.html 8 | tags 9 | genmobi.sh 10 | *.mobi 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | COPTS=-O -g -Wall -Werror 3 | 4 | .PHONY: all clean 5 | 6 | all: wrapalloc.so 7 | 8 | %.so: %.c 9 | $(CC) $(COPTS) -fPIC -shared $< -o $@ -ldl || \ 10 | $(CC) $(COPTS) -fPIC -shared $< -o $@ 11 | 12 | clean: 13 | rm -rf *.so *.o *.lo 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Name 2 | ==== 3 | 4 | wrapalloc - Wraps up glibc's memory allocation and freeing API functions to ease dynamic tracing 5 | 6 | Synopsis 7 | ======== 8 | 9 | LD_PRELOAD=/path/to/wrapalloc/wrapalloc.so your_app 10 | 11 | Description 12 | =========== 13 | 14 | The glibc binaries shipped with most mainstream Linux distributions usually suffer from the incorrect 15 | debuginfo generated by gcc under very aggressive optimizaton flags. 16 | 17 | This LD_PRELOAD library wraps up the common glibc API functions for memory allocations and de-allocations 18 | so that dynamic tracing tools like those based on systemtap can work reliably. 19 | 20 | Building 21 | ======== 22 | 23 | $ make 24 | 25 | Author 26 | ====== 27 | 28 | Yichun Zhang (agentzh) 29 | 30 | -------------------------------------------------------------------------------- /wrapalloc.c: -------------------------------------------------------------------------------- 1 | #ifndef DDEBUG 2 | #define DDEBUG 0 3 | #endif 4 | 5 | 6 | #define _GNU_SOURCE 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | #if DDEBUG 13 | # define dd(...) \ 14 | fprintf(stderr, "wrapalloc: "); \ 15 | fprintf(stderr, __VA_ARGS__); \ 16 | fprintf(stderr, " at %s line %d.\n", __FILE__, __LINE__) 17 | #else 18 | # define dd(...) 19 | #endif 20 | 21 | 22 | #define init_libc_handle() \ 23 | if (libc_handle == NULL) { \ 24 | libc_handle = RTLD_NEXT; \ 25 | } 26 | 27 | #define init_orig(name) \ 28 | init_libc_handle(); \ 29 | if (orig_ ## name == NULL) { \ 30 | orig_ ## name = dlsym(libc_handle, #name); \ 31 | if (orig_ ## name == NULL) { \ 32 | fprintf(stderr, "mockeagain: could not find the underlying " #name \ 33 | ": %s\n", dlerror()); \ 34 | exit(1); \ 35 | } \ 36 | } 37 | 38 | 39 | static void *libc_handle = NULL; 40 | 41 | 42 | typedef void *(*malloc_func_t)(size_t); 43 | typedef void *(*realloc_func_t)(void *, size_t); 44 | typedef void *(*calloc_func_t)(size_t, size_t); 45 | typedef int (*posix_memalign_func_t)(void **, size_t, size_t); 46 | typedef void *(*memalign_func_t)(size_t, size_t); 47 | typedef void *(*aligned_alloc_func_t)(size_t, size_t); 48 | typedef void *(*valloc_func_t)(size_t); 49 | typedef void *(*pvalloc_func_t)(size_t); 50 | typedef void (*free_func_t)(void *); 51 | 52 | 53 | void __attribute__ ((noinline)) probe_alloc_event(void *memptr, size_t bytes) 54 | { 55 | } 56 | 57 | void __attribute__ ((noinline)) probe_free_event(void *memptr) 58 | { 59 | } 60 | 61 | void * 62 | malloc(size_t bytes) 63 | { 64 | void *ptr; 65 | static malloc_func_t orig_malloc = NULL; 66 | 67 | init_orig(malloc); 68 | ptr = orig_malloc(bytes); 69 | probe_alloc_event(ptr, bytes); 70 | return ptr; 71 | 72 | } 73 | 74 | 75 | void * 76 | realloc(void *oldmem, size_t bytes) 77 | { 78 | void *ptr; 79 | static realloc_func_t orig_realloc = NULL; 80 | 81 | init_orig(realloc); 82 | probe_free_event(oldmem); 83 | ptr = orig_realloc(oldmem, bytes); 84 | probe_alloc_event(ptr, bytes); 85 | return ptr; 86 | } 87 | 88 | 89 | void * 90 | calloc(size_t n, size_t elem_size) 91 | { 92 | void *ptr; 93 | static calloc_func_t orig_calloc = NULL; 94 | 95 | init_orig(calloc); 96 | ptr = orig_calloc(n, elem_size); 97 | probe_alloc_event(ptr, n * elem_size); 98 | return ptr; 99 | } 100 | 101 | 102 | int 103 | posix_memalign (void **memptr, size_t alignment, size_t size) 104 | { 105 | int rc; 106 | static posix_memalign_func_t orig_posix_memalign = NULL; 107 | 108 | init_orig(posix_memalign); 109 | rc = orig_posix_memalign(memptr, alignment, size); 110 | probe_alloc_event(*memptr, size); 111 | return rc; 112 | } 113 | 114 | 115 | void * 116 | memalign(size_t alignment, size_t bytes) 117 | { 118 | void *ptr; 119 | static memalign_func_t orig_memalign = NULL; 120 | 121 | init_orig(memalign); 122 | ptr = orig_memalign(alignment, bytes); 123 | probe_alloc_event(ptr, bytes); 124 | return ptr; 125 | } 126 | 127 | 128 | void * 129 | aligned_alloc(size_t alignment, size_t bytes) 130 | { 131 | void *ptr; 132 | static memalign_func_t orig_aligned_alloc = NULL; 133 | 134 | init_orig(aligned_alloc); 135 | ptr = orig_aligned_alloc(alignment, bytes); 136 | probe_alloc_event(ptr, bytes); 137 | return ptr; 138 | } 139 | 140 | 141 | void * 142 | valloc(size_t bytes) 143 | { 144 | void *ptr; 145 | static valloc_func_t orig_valloc = NULL; 146 | 147 | init_orig(valloc); 148 | ptr = orig_valloc(bytes); 149 | probe_alloc_event(ptr, bytes); 150 | return ptr; 151 | } 152 | 153 | 154 | void * 155 | pvalloc(size_t bytes) 156 | { 157 | void *ptr; 158 | static pvalloc_func_t orig_pvalloc = NULL; 159 | 160 | init_orig(pvalloc); 161 | ptr = orig_pvalloc(bytes); 162 | probe_alloc_event(ptr, bytes); 163 | return ptr; 164 | } 165 | 166 | 167 | void 168 | free(void *ptr) 169 | { 170 | static free_func_t orig_free = NULL; 171 | 172 | init_orig(free); 173 | orig_free(ptr); 174 | probe_free_event(ptr); 175 | } 176 | --------------------------------------------------------------------------------