malloc_hook(3)

malloc デバッグ用の変数 · man3 · 日本語

MALLOC_HOOK(3) Linux Programmer's Manual 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)EN, mtrace(3)EN

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

2020-11-01 GNU