MALLOC_HOOK(3)

名前
__malloc_hook, __malloc_initialize_hook, __memalign_hook, __free_hook, __realloc_hook, __after_morecore_hook - malloc デバッグ用の変数

書式
#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);

説明
GNU C ライブラリでは、適切なフック関数 (hook function) を指定することで malloc(3), realloc(3), free(3) の動作を変更することができる。例えば、動的にメモリー割り当てを行う プログラムのデバッグにこれらのフックを使うことができる。

変数 __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) が呼ばれた後で毎回呼び出される関数へのポインターである。

準拠
これらの関数は GNU による拡張である。

注意
The use of these hook functions is not safe in multithreaded programs, and they are now deprecated. From glibc 2.24 onwards, the __malloc_initialize_hook variable has been removed from the API. Programmers should instead preempt calls to the relevant functions by defining and exporting functions such as "malloc" and "free".

例
これらの変数の使い方の簡単な例を以下に示す。

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

        return result;
    }

関連項目
mallinfo(3), malloc(3), mcheck(3), mtrace(3)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。