Linux 環境で、「glibc detected *** free(): invalid pointer」エラーが発生した場合、原因となっているコード行を特定するにはどうすればよいですか?
強制的に中止する方法はありますか? これを制御するための ENV var があることを覚えていますか?
glibc エラーの gdb にブレークポイントを設定するには?
Linux 環境で、「glibc detected *** free(): invalid pointer」エラーが発生した場合、原因となっているコード行を特定するにはどうすればよいですか?
強制的に中止する方法はありますか? これを制御するための ENV var があることを覚えていますか?
glibc エラーの gdb にブレークポイントを設定するには?
envを 2 に設定すると、「free(): 無効なポインター」エラーが検出されたときにMALLOC_CHECK_
glibc が呼び出されると思います。abort()
環境変数の名前の末尾のアンダースコアに注意してください。
が 1 の場合MALLOC_CHECK_
、glibc は「free(): 無効なポインター」を出力します (その他のエラーについては同様の printfs を出力します)。が 0 の場合MALLOC_CHECK_
、glibc はそのようなエラーを黙って無視し、単に戻ります。が 3 の場合MALLOC_CHECK_
、glibc はメッセージを出力してから を呼び出しますabort()
。つまり、ビットマスクです。
0 ~ 3 の引数を指定して呼び出すこともできmallopt(M_CHECK_ACTION, arg)
、 と同じ結果が得られMALLOC_CHECK_
ます。
MALLOC_CHECK_
「free(): 無効なポインター」というメッセージが表示されているので、既に を設定または呼び出しているに違いないと思いますmallopt()
。デフォルトでは、glibc はこれらのメッセージを出力しません。
デバッグ方法については、ハンドラーをインストールするのSIGABRT
がおそらく最善の方法です。ハンドラーにブレークポイントを設定するか、意図的にコア ダンプをトリガーすることができます。
valgrind を入手することをお勧めします。
valgrind --tool=memcheck --leak-check=full ./a.out
gdbにブレークポイントを設定するには?
(gdb) b filename:linenumber // 例 b main.cpp:100
強制的に中止する方法はありますか? これを制御するための ENV var があることを覚えていますか?
デフォルトで中止されたという印象を受けました。デバッグ バージョンがインストールされていることを確認します。
または、libdmalloc5 を使用します。「システムのmalloc',
realloc'、calloc',
free' およびその他のメモリ管理ルーチンの代わりに、実行時に構成可能な強力なデバッグ機能を提供します。これらの機能には、メモリ リーク追跡、フェンスポスト書き込み検出、ファイル/ラインなどがあります。数の報告、および統計の一般的なログ。"
これをリンクコマンドに追加します
-L/usr/lib/debug/lib -ldmallocth
glibc がアボートをトリガーすると、gdb は自動的に制御を返す必要があります。
または、SIGABRT のシグナル ハンドラーをセットアップして、スタック トレースを fd (ファイル記述子) にダンプすることもできます。以下、mp_logfile は FILE*
void *array[512 / sizeof(void *)]; // 100 is just an arbitrary number of backtraces, increase if you want.
size_t size;
size = backtrace (array, 512 / sizeof(void *));
backtrace_symbols_fd (array, size, fileno(mp_logfile));
一般的に、glibc を再コンパイルする必要があるようです。
実行している環境はわかりませんが、OS X 用にコードを再コンパイルできる場合、そのバージョンの libc には、この環境変数をリッスンする free() があります。
MallocErrorAbort If set, causes abort(3) to be called if an
error was encountered in malloc(3) or
free(3) , such as a calling free(3) on a
pointer previously freed.
OS X の free() の man ページに詳細があります。
Linux を使用している場合は、Valgrindを試してください。ハンティング不可能なバグを見つけることができます。