Search code examples
cmallocglibc

How to use __malloc_hook?


In GNU C Library Reference Manual, there is an example program(p.65), But I don't know what the three sentences: __malloc_hook = old_malloc_hook; old_malloc_hook = __malloc_hook; __malloc_hook = my_malloc_hook; mean. Especailly the second one, who can explain for me? thanks.

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;
}

I write a little program to test it:

#include <stdio.h>
#include <malloc.h>

/* Prototypes for our hooks.  */
static void my_init_hook(void);
static void *my_malloc_hook(size_t, const void *);

/* Variables to save original hooks. */
static void *(*old_malloc_hook) (size_t, 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;
    __malloc_hook = my_malloc_hook;
}

static void *my_malloc_hook(size_t size, const void *caller)
{
    void *result;

    /* Restore all old hooks */
    __malloc_hook = old_malloc_hook;

        printf("1: __malloc_hook = %x  old_malloc_hook = %x\n", __malloc_hook, old_malloc_hook);
    /* Call recursively */
    result = malloc(size);

        printf("2: __malloc_hook = %x  old_malloc_hook = %x\n", __malloc_hook, old_malloc_hook);


    /* Save underlying hooks */
    old_malloc_hook = __malloc_hook;

        printf("3: __malloc_hook = %x  old_malloc_hook = %x\n", __malloc_hook, old_malloc_hook);
    /* printf() might call malloc(), so protect it too. */
    printf("malloc(%u) called from %p returns %p\n",
           (unsigned int)size, caller, result);

    /* Restore our own hooks */
    __malloc_hook = my_malloc_hook;
        printf("4: __malloc_hook = %x  old_malloc_hook = %x\n", __malloc_hook, old_malloc_hook);

    return result;
}

int main(void)
{
        char *p;
        p = malloc(10);
        free(p);
        return 0;
}

the result of the program is :

1: __malloc_hook = 0  old_malloc_hook = 0
2: __malloc_hook = 0  old_malloc_hook = 0
3: __malloc_hook = 0  old_malloc_hook = 0
malloc(10) called from 0xb7797f38 returns 0x932c008
4: __malloc_hook = 804849d  old_malloc_hook = 0

but now I have more problems, why old_malloc_hook are all 0, in 1,2,3, why __malloc_hook are 0? I am really confused. Help me.


Solution

  • As far as I can tell, everything is working exactly as expected and the output is fine.

    The variable, __malloc_hook, is 0 (or null) probably because the system's default is to not have a malloc hook.

    As David Schwartz mentioned above, saving the original __malloc_hook is important so that it can be restored just before the original malloc() is called. That's the line just below the comment /* Restore all old hooks */. I'm guessing that in this specific case, it's unnecessary, since the original malloc hook is null, but to be safe it should be done.

    Please rest assured that this code is running just like you want it to. For now, I would simply let this stew for a while and perhaps a light-bulb will go off and one day, you'll understand it completely. (Sorry, but that's the best I can do today.)