freeし忘れた領域を教えてくれるmtrace
mtraceについてのメモ。
何ができるのか
mallocして、freeし忘れたと思われる領域をピックアップしてくれる。 ただし、GNU拡張機能なので、どこの環境でも使えるわけではない。
どうやるのか
3行のソース修正、デバッグオプションビルド、トレースしながら実行、解析
の順に行う。
1. ソース修正
下記三行を追加する。
- mcheck.hをinclude。
- トレース開始地点にmtrace();
- トレース終了地点にmuntrace();
2. ビルド
-g オプションを付けてデバッグビルドするだけ。
$ gcc -g test.c
3. 実行
MALLOC_TRACE環境変数で、トレース結果の出力先を指定してから実行する。
$ MALLOC_TRACE=output.txt ./a.out
4. 解析
mtraceコマンドにトレース結果ファイルとトレース対象のバイナリを引数として与えて解析する。 mtraceコマンドは、CentOSの場合は、glibc-utilsに含まれている。
free忘れと思われるアドレス、サイズ、呼び元が出力される。 よそのライブラリ内部など、デバッグビルドしていない箇所が呼び元の場合、実行アドレスのみの表示になるようだ。
$ mtrace a.out output.txt
サンプル
下記サンプルコードでお試し。
#include <stdlib.h> #include <mcheck.h> int main(void){ int i; char* p_str = NULL; mtrace(); for(i=0; i<10; i++){ p_str = (char*)malloc(sizeof(char)*4);/* LEAK */ } muntrace(); return 0; }
これを-gオプションを付けてコンパイル。
$ gcc -g test.c
トレース結果の出力先を指定して実行。
$ MALLOC_TRACE=./trace.txt ./a.out
mtraceコマンドで出力結果を解析。
下記のようにアドレス、サイズ、呼び元が出力される。
$ mtrace a.out trace.txt Memory not freed: ----------------- Address Size Caller 0x00000000020d4460 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4480 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d44a0 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d44c0 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d44e0 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4500 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4520 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4540 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4560 0x4 at /home/.../mtrace_test/test.c:11 0x00000000020d4580 0x4 at /home/.../mtrace_test/test.c:11 $