#include <malloc.h> void *(*__malloc_hook)(size_t size, const void *caller); void *(*__realloc_hook)(void *ptr, size_t size, const void *caller); void *(*__memalign_hook)(size_t alignment, size_t size, const void *caller); void (*__free_hook)(void *ptr, const void *caller); void (*__malloc_initialize_hook)(void); void (*__after_morecore_hook)(void);
変数 __malloc_initialize_hook は malloc の実装が初期化される際に一度だけ呼ばれる関数へのポインターである。 この変数は書き換え可能 (weak) であり、アプリケーション内で 以下のような定義で上書きできる:
void (*__malloc_initialize_hook)(void) = my_init_hook;
なお、関数 my_init_hook() で全てのフックの初期化をすることができる。
__malloc_hook, __realloc_hook, __memalign_hook, __free_hook で指される 4 つの関数は、各々 malloc(3), realloc(3), memalign(3), free(3) とよく似たプロトタイプを持っているが、 一番最後の引数 caller をとる点が異なる。 引数 caller には、 malloc(3) などの呼び出し元 (caller) のアドレスが格納される。
変数 __after_morecore_hook は、領域の追加要求があり sbrk(2) が呼ばれた後で毎回呼び出される関数へのポインターである。
#include <stdio.h> #include <malloc.h>
/* 使おうとするフックのプロトタイプ宣言 */ static void my_init_hook(void); static void *my_malloc_hook(size_t, const void *);
/* 元々のフックを保存するための変数 */ static void *(*old_malloc_hook)(size_t, const void *);
/* C ライブラリから呼ばれる初期化フックを上書きする */ 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;
/* 元々のフックを全て戻す */
__malloc_hook = old_malloc_hook;
/* malloc の再帰的呼び出し */
result = malloc(size);
/* 現在設定されているフック (underlying hook) を保存する */
old_malloc_hook = __malloc_hook;
/* printf() は malloc() を呼び出す可能性があるので
ここでもガードを行う (元々のフックのままにしておく) */
printf("malloc(%zu) called from %p returns %p\n",
size, caller, result);
/* ユーザーが使おうとするフックを再設定する */
__malloc_hook = my_malloc_hook;
[man1]
[man2]
[man3]
[man4]
[man5]
[man6]
[man7]
[man8]
[a]
[b]
[c]
[d]
[e]
[f]
[g]
[h]
[i]
[j]
[k]
[l]
[m]
[n]
[o]
[p]
[q]
[r]
[s]
[t]
[u]
[v]
[w]
[x]
[y]
[z]