簡易mallocデバッグメモ
Linux、FreeBSDについて昔メモっておいたものをここに残しておく。 いまはもっと簡単なものもあるし、もっと複雑なものもある。あるいはgc使うのもいいだろう。
Linux(glibc):
malloc(), calloc(), realloc() は失敗すると errno に ENOMEM が入る。
デバッグには環境変数 MALLOC_CHECK_ をいじる。値は、
0 ヒープの破壊を黙って無視
1 診断メッセージを表示
2 abort() を呼び出す
他にも
MALLOC_TRIM_THRESHOLD_
MALLOC_TOP_PAD_
MALLOC_MMAP_THRESHOLD_
MALLOC_MMAP_MAX_
MALLOC_TRACE
などの環境変数(?)があるようだ。
malloc 系の関数には hook をかけることができる。
変数 __malloc_hook, __realloc_hook, __free_hook, __memalign_hook に関数ポインタを設定する。
メモリアロケーションの状況を struct mallinfo mallinfo (void); で取ってくることができる。
void mtrace(void) でメモリ割り当て状況をトレースできる。
MALLOC_TRACE 環境変数(ファイル名が入っている)を見て、
ファイルに状況を書き込む。mcheck.h を参照。
void muntrace(void) でトレースを終了できる。
mcheck() という関数があって、malloc の一貫性チェックを
有効にする。これを使って、
(gdb) break main
Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>call mcheck(0)
>continue
>end
(gdb) ...
みたいなことをするらしい。gcc -lmcheck してもいいみたい。
デフォルトでは一貫性がなかったら abort する。
FreeBSD:
環境変数 MALLOC_OPTIONS を使う。/etc/malloc.conf に
シンボリックリンクとして値を埋め込むとシステムワイドな設定になる。
値は、
A abort() を呼び出す
J malloc(), realloc(), reallocf() や free() されたメモリを 0xd0 でfill
J は R も兼ねる
H 割り当て関数によって使われなくなったページに関するヒントをカーネルに
渡す。ページングが遅いシステムで有効。デフォルトはオフ
R realloc() 時にすでに十分な量のメモリが確保されている場合でも強制的に
realloc する
U ktrace(1) のために utrace エントリを生成する
V malloc(0) が NULL ポインタを返すようにする。SystemV コンパチ。
X オプションとは共存できない
X 割り当て関数で失敗が起こったら、診断メッセージを stderr に表示して、
core を吐く
Z 暗黙に J と R を設定したことになる。ただし 0xd0 ではなく、ゼロクリア
パフォーマンスは落ちる
< キャッシュサイズを半減。デフォルトは16ページ。複数設定できる
> キャッシュサイズを倍増。デフォルトは16ページ。複数設定できる
J や Z はテストとデバッグに使えるだろう。
Solaris:
不明。Debug Malloc Library でも使うしかないだろう。
http://dmalloc.com/
LeakTracer
http://www.andreasen.org/LeakTracer/
# LeakCheck コマンド
# leak-analyze
でなんか出てくるらしい。C++ 専用。