malloc のオーバーライドの問題

解決した問題:

void* my_malloc(size_t size, const char *file, int line, const char *func)
{

    void *p = malloc(size);
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
    return p;
}
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)

glibc では malloc_hook(3) が存在する 適切として 独自の malloc をグローバルに挿入する方法 関数。

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

static void *(*old_malloc_hook)(size_t, const void *);

static void *new_malloc_hook(size_t size, const void *caller) {
    void *mem;

    __malloc_hook = old_malloc_hook;
    mem = malloc(size);
    fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
    __malloc_hook = new_malloc_hook;

    return mem;
}

static void init_my_hooks(void) {
    old_malloc_hook = __malloc_hook;
    __malloc_hook = new_malloc_hook;
}

void (*__malloc_initialize_hook)(void) = init_my_hooks;
$ cat >mem.c <<'EOF'
(the code above)
EOF
$ cat >main.c <<'EOF'
#include <stdio.h>
#include <stdlib.h>
int main() {
    char *buf = malloc(50);
    sprintf(buf, "Hello, world!");
    puts(buf);
    free(buf);
    return 0;
}
EOF
$ cc mem.c main.c
$ ./a.out
0x40077e: malloc(50) = 0x22f7010
Hello, world!

( __attribute__((constructor)) を使用できます 、しかしそのトリックは必要ありません:Glibc は手軽に __malloc_initialize_hook を提供します main より前に実行コードをロードする別の方法として .)


マクロ置換問題の両方を修正し、LINE を作成するには などは、期待どおりに機能します:

#define malloc(X) my_malloc((X), __FILE__, __LINE__, __FUNCTION__)

void* my_malloc(size_t size, const char *f, int l, const char *u)
{

    void *p = (malloc)(size);
    printf ("Allocated = %s, %d, %s, %x\n", f, l, u, p);
    return p;
}

(その方法 LINE 友人は、マクロが展開された場所で評価されます。それ以外の場合は、常に同じになります)。

名前 (malloc) を囲む 括弧内はマクロ malloc を防ぎます これは関数のようなマクロであるため、展開されません。