3

gdb で誤って初期化されていないデータをデバッグしようとすると、煩わしい場合があることがわかりました。コマンドラインから直接実行するとプログラムはクラッシュしますが、gdb で検査中はクラッシュしません。gdb のヒープは多くの場合クリーン (すべてゼロ) のようですが、コマンド ラインからは明らかにそうではありません。

これには理由がありますか?もしそうなら、意図的に gdb や gcc にヒープをダーティにするように指示できますか? malloc()IE、およびに常にランダムなデータを与える「デバッグ」アロケーターを指定する方法はありますnewか? これには特別な libc が関係していると思いますか? 明らかに、リンカー オプションを変更せずにこれを行う方法があれば、リリース バージョンがデバッグ バージョンとできるだけ同じになるようにするとよいでしょう。

私は現在 MinGW-w64 (gcc 4.7 ベース) を使用していますが、一般的な回答に興味があります。

4

2 に答える 2

1

これを行う Linux の方法は、valgrind を使用することです。Mac OS X には、割り当てのデバッグを制御する環境変数があります。 malloc については、Mac OS X のマニュアル ページを参照してください。Mac OS X の Valgrind サポートが表示され始めていますが、これを書いている時点では 10.8 のサポートは完全ではありません。

MinGW-w64 を使用しているため、Windows を使用していると想定しています。この SO の質問は、Windows での valgrind の代替手段について語っているようです。1 つの解決策は、valgrind の下の Linux ボックスで Wine でアプリを実行することです。

プログラムが valgrind の下で実行されている場合、CPU で直接実行されているわけではありません。Valgrind はすべての命令をシミュレートしているため、単純にデバッガーをアタッチすることはできません。これを機能させるには、valgrind GDB サーバーを使用する必要があります。詳細については、このページを参照してください。

別のアプローチは、callocの代わりに使用することですmalloc。これにより、ヒープ割り当てがゼロになります。これにより、故意にダーティ ヒープが生成されることはありませんが、少なくともデバッガーの有無にかかわらず一貫した動作が得られます。

于 2013-03-18T16:25:43.553 に答える
0

はい、GDB はすべてをゼロにします。これは便利であり、非常に煩わしいことでもあります。すべてが明確に定義された状態にあることが保証されている限り、便利です (メモリ内にランダムな値はなく、ゼロのみ)。つまり、理論的には、デバッグ中に厄介な驚きはありません。
実際には、これが厄介なところですが、理論は時々見事に失敗します。悪名高い「正常に動作するが、デバッガーでクラッシュ!?!」または「デバッガーでは正常に動作しますが、それ以外の場合はクラッシュしますか?!」問題はその一例です。通常、これは初期化されていないポインターと意図されたif(ptr != NULL)場所の組み合わせであり、デバッガーがメモリをゼロに初期化するため、「正当な理由なし」で完全に爆発し、テストが意図したとおりに実行されません。

によって割り当てられたデータを意図的にガーブリングすることに関するあなたの質問についてmalloc、GCC は malloc フックをサポートしています (こちらのドキュメントSO に関する質問を参照してください)。

これにより、非常に簡単で邪魔にならない方法で、すべての呼び出しをmalloc独自の関数にリダイレクトできます。そこから、実数mallocを呼び出して、割り当てられたブロックをガベージ (または のような無効なポインター マジック値DEADBEEF) で満たすことができます。

に関してはoperator new、これはたまたまラッパーですmalloc(これは実装の詳細ですが、malloc フックは既に非移植性であるため、それに依存しても事態が悪化することはありません)、したがって、malloc フックはすでにこれに対処している必要があります。

于 2013-03-18T17:02:03.950 に答える