3

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.

Fei Xue
  • 1,995
  • 5
  • 19
  • 29

3 Answers3

5

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.)

Randy Stegbauer
  • 1,104
  • 2
  • 11
  • 25
  • 1
    "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." Now I understand, for the case that old_malloc_hook is null, it seems the sentence `old_malloc_hook=__malloc_hook` has no sense, but it's necessary for the case that old_malloc_hook is not null. – Fei Xue Jul 09 '12 at 00:48
  • Yes, I don't know why but using old_malloc_hook =__malloc_hook causing crash in the android NDK. – Murali Krishna Bellamkonda Oct 10 '22 at 06:38
4

It's documented pretty well in the manual page.

  1. old_malloc_hook = __malloc_hook;: This saves the current malloc hook in a variable called old_malloc_hook. Presumably, we're saving it because we're about to change it.

  2. __malloc_hook = my_malloc_hook;: This changes the current malloc hook to be my_malloc_hook.

  3. __malloc_hook = old_malloc_hook;: The changes the malloc hook back to whatever it was before we changed it, the value we saved in old_malloc_hook.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • `result = malloc (size);`: This will change `old_malloc_hook`? If not , why we save it from `__malloc_hook`, because we just set `__malloc_hook` to `old_malloc_hook` ? – Fei Xue Jul 06 '12 at 06:49
  • Well, the __malloc_hook manipulations change the internal cogwheels of the malloc() function. result = malloc( size ) calls the malloc function (which again will use whatever malloc hook is currently active). – user422005 Jul 06 '12 at 07:00
  • @ccsnailpp: We save the old one so we can put it back when we're done. We save it because *we* are going to change it and want to leave things the way we found them so we don't screw up anything else. – David Schwartz Jul 06 '12 at 07:11
  • @DavidSchwartz: Sorry, I don't understand `old_malloc_hook = __malloc_hook;`. Can you give me an example, if we delete this sentence, what will happen? – Fei Xue Jul 06 '12 at 07:42
  • @ccsnailpp: If you remove that, then the old malloc hook won't be saved and this code can't put things back the way it found them when it's done. – David Schwartz Jul 06 '12 at 07:53
0

I think what these answers are missing is the following:

old_malloc_hook is NULL at the start and then malloc_hook = old_malloc_hook makes sure that the hook is disabled and we don't infinitely recurse while calling the actual library function malloc inside the function my_malloc_hook.