ヒープを破損しているマルチスレッドC++ アプリケーションで作業しています。この破損を特定するための通常のツールは適用できないようです。ソース コードの古いビルド (18 か月前) は最新のリリースと同じ動作を示します。欠点としては、ソース デルタを使用して、バグがいつ導入されたかを特定できません。リポジトリには多くのコード変更があります。
クラッシュ動作のプロンプトは、このシステムでスループットを生成することです。つまり、内部表現に変更されたデータのソケット転送です。アプリに定期的に例外を発生させる一連のテスト データがあります (さまざまな場所、さまざまな原因 - ヒープ割り当ての失敗など: ヒープの破損)。
この動作は、CPU パワーまたはメモリ帯域幅に関連しているようです。マシンのそれぞれが多ければ多いほど、クラッシュしやすくなります。ハイパースレッディング コアまたはデュアルコア コアを無効にすると、破損の割合が減少します (ただし、完全にはなくなりません)。これは、タイミング関連の問題を示唆しています。
問題は次のとおりです:
軽量のデバッグ環境 (たとえばVisual Studio 98 / AKA MSVC6
) で実行すると、ヒープの破損はかなり簡単に再現できますalloc;
。洗練されたデバッグ環境 (Rational Purify、VS2008/MSVC9
または Microsoft Application Verifier でさえ) システムはメモリ速度の制約を受け、クラッシュしません (メモリの制約: CPU が を超えていない50%
、ディスク ライトが点灯していない、プログラムが可能な限り高速に動作している、ボックスが1.3G
2G の RAM を消費している) . したがって、問題を再現できる (ただし原因は特定できない) か、原因または再現できない問題を特定できるかの選択肢があります。
次の場所に関する私の現在の最良の推測は次のとおりです。
- 非常に汚れたボックスを取得します (現在の開発ボックスを置き換えるには: 2Gb RAM に
E6550 Core2 Duo
); これにより、強力なデバッグ環境での実行時に誤動作を引き起こすクラッシュを再現できるようになります。また - 演算子
new
andを書き換えて、 anddelete
を使用し、使用が終了したらすぐにメモリを読み取り専用としてマークします。実行して、解放されたメモリに書き込んでいる悪者を OS に捕まえさせます。はい、これは絶望のしるしです。一体誰が書き直しているのですか?! これにより、Purify などと同じくらい遅くなるのだろうか。VirtualAlloc
VirtualProtect
MSVC6
new
delete
いいえ、Purify インスツルメンテーションを組み込んで出荷することはできません。
同僚がちょうど通り過ぎて、「スタック オーバーフローですか? 今、スタック オーバーフローが発生していますか?!?」と尋ねました。
そして今、質問:ヒープ破損者を見つけるにはどうすればよいですか?
更新: バランスが取れてnew[]
おりdelete[]
、問題の解決に向けて長い道のりを歩んでいるようです. アプリがクラッシュするまでに 15 分ではなく、約 2 時間かかるようになりました。まだありません。さらに提案はありますか?ヒープの破損が続く。
更新: Visual Studio 2008 でのリリース ビルドは劇的に優れているようです。現在の疑惑は、にSTL
付属する実装にかかっていVS98
ます。
- 問題を再現します。
Dr Watson
さらなる分析に役立つ可能性のあるダンプが生成されます。
私はそれをメモしておきますが、ワトソン博士がつまずくのは事後であって、ヒープが踏みつけられたときではないことを懸念しています.
別の試み
WinDebug
は、非常に強力であると同時に軽量でもあるデバッグツールとして使用することです。
現時点では、これもうまくいきました。何かがうまくいかない限り、あまり助けにはなりません。行為中の荒らしを捕まえたい。
おそらく、これらのツールを使用すると、少なくとも問題を特定のコンポーネントに絞り込むことができます。
私はあまり希望を持っていませんが、絶望的な時代が求められています...
また、プロジェクトのすべてのコンポーネントが正しいランタイム ライブラリ設定 (
C/C++ tab
VS 6.0 プロジェクト設定のコード生成カテゴリ) を持っていることを確認しますか?
いいえ、そうではありません。明日、ワークスペース (58 個のプロジェクト) を調べて、それらがすべてコンパイルされ、適切なフラグでリンクされていることを確認するのに数時間を費やします。
更新: これには 30 秒かかりました。ダイアログですべてのプロジェクトを選択し
Settings
、適切な設定を持たないプロジェクトが見つかるまで選択を解除します (それらはすべて適切な設定を持っていました)。