I am writing this blog to share the information I had regarding adding malloc hooks in linux. I have used the malloc hooks only for the GNU gcc compiler and I am not sure about the hooks available in other open source/vendor compilers.
Consider the following simple program where a memory is allocated
int main() {
int *ptr = (int *) malloc(sizeof(int));
if (!ptr)
return -1;
free(ptr);
return 0;
}
My desire was to get notified whenever memory is allocated or freed. This might be an useful feature for debugging or in general to handle your own memory management. C++ provides a convenient way of overloading new and delete. Was searching how to track for C programs. Fortunately, GNU gcc provides hooks for it.
The GNU C library lets you modify the behavior of malloc, realloc, and free by specifying
appropriate hook functions. You can use these hooks to help you debug programs that use
dynamic memory allocation, for example.
The hook variables are declared in ‘malloc.h’. They are:
1) __malloc_hook : You should define the function below to look like malloc
void *function (size_t size, const void *caller )
2) __realloc_hook: You should define the function below to look like realloc
void *function (void *ptr, size_t size, const void *caller )
3) __free_hook: You should define the function below to look like free
void function (void *ptr, const void *caller )
4) __memalign_hook: You should define the function below to look like memalign
void *function (size_t alignment, size_t size, const void *caller )
The value of caller is the return address found on the stack when the malloc/realloc/free/memalign function was called.
6) __malloc_initialize_hook
The value of this variable is a pointer to a function that is called once when the malloc implementation is initialized. Its a weak variable, so it can be overridden with a definition like:
void (*__malloc_initialize_hook ) (void) = my_init_hook;
I have pasted below the small sample program in using these hooks.
#include<stdio.h>
#include<malloc.h>
/* Prototypes for our hooks. */
static void my_init_hook (void);
static void * (*old_malloc_hook) (size_t, const void *);
static void (*old_free_hook) (void*, const void *);
static void *my_malloc_hook (size_t, const void *);
static void my_free_hook (void*, const void *);
/* Override initializing hook from the C library. */
void (*__malloc_initialize_hook) (void) = my_init_hook;
static void my_init_hook (void) {
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
static void * my_malloc_hook (size_t size, const void *caller) {
void *result;
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
result = malloc (size);
/* Save underlying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call malloc, so protect it too. */
printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
return result;
}
static void my_free_hook (void *ptr, const void *caller) {
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
free (ptr);
/* Save underlying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call free, so protect it too. */
printf ("freed pointer %p\n", ptr);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
int main() {
int *a = NULL;
a = (int *) malloc(sizeof(int));
free(a);
return 0;
}
__malloc_hook, __free_hook: installs a function that prints out information every time malloc or free is called.
This is a big powerful feature where own malloc and free can be implemented and called.
Build and ran this program getting the following output.
./a.out
malloc (4) returns 0x9aa4008
freed pointer 0x9aa4008
As you can see above, a print statement displaying the address of the allocated block is shown for both malloc and free statements. A simple hook was implemented above. More powerful and complex hook could be implemented based on the scenarios in using them.
Please refer the GNU gcc reference manual for more information.
Please let me know whether I am wrong or missing something. You can improve upon it by providing comments/suggestions.

No comments:
Post a Comment