COM+ アプリケーション、Windows XP SP 3 上の MS Visual Studio 6、SP 6 でビルド、リモートでデバッグ。
私の主な質問はこれです。「削除」に入ることができるのに、「新規」に入ることができないのはなぜですか? 私は主に、何を調べるべきかについてのアイデアを探しています。
私は、慣れてきたばかりのかなり大きなプロジェクトに取り組んでいます。現在の問題は、リリース ビルドが最終的にワーキング セットを使い果たしてクラッシュするヒープ破損の問題です。この問題は非常に広範囲に及ぶため、次のコードでヒープが破損します。
int * iArray = new int [100];
delete [] iArray;
「delete」でデバッグ出力に「ヒープ [dllhost.exe]: rtlvalidateheap に指定された無効なアドレス」が表示されるため、「ヒープを破損する」と言います。
「削除」呼び出しに問題なくステップインでき、適切な呼び出し (...\Microsoft Visual Studio\VC98\CRT\SRC の DELOP.cpp にあります) を呼び出しているようですが、何らかの理由でステップインできません。 「new」への任意の呼び出し。ここでストローをつかんでいますが、コードベースのどこかで誰かが「new」演算子を上書きしたような気がします。私が見ているコードは意図せずにそれを使用しています。リリース ビルドの症状は、メモリが 1 つのヒープに割り当てられ、別のヒープから削除されようとしているように見えます。少なくともそれは私の予感です。
編集:ああ!申し訳ありませんが、投稿が早すぎました。もっと情報を提供する必要がありました。
コード ベースを検索したところ、いくつかのオーバーライドが見つかりましたが、それらはすべてクラス内にあり、グローバルに定義されていません。クラスにない唯一のものは次のとおりです。
struct _new_selector
{
};
inline void* operator new(size_t, void *ptr, _new_selector)
{
return (ptr);
}
しかし、それは新しい配置であり、この状況ではカウントされないと確信しています. 元の「新しい」ために足を踏み入れるべきライブラリは何ですか? 「削除」と同じだと思いますが、そうでない場合は、デバッグ情報がないだけでしょうか?
編集2:これをいじって、デバッグビルドではこの問題が存在しないことがわかりました。ランタイム ライブラリは既に調べましたが、デバッグに /MD と /MDd を使用しています。それだけでなく、確認のために /MDd jut を使用してリリース バージョンをビルドしましたが、それでも変更はありませんでした。デバッグ ビルドとリリース ビルドの両方のマップを見ると、新しい演算子 (マングリングを含む) は次の場所にあります。
リリース:
0001:00061306 ??2@YAPAXI@Z 10062306 f MSVCRTD:MSVCRTD.dll
0002:00000298_imp ??2@ YAPAXI @Z 1006e298 MSVCRTD:MSVCRTD.dll
デバッグ:
0001:00077d06 ??2@YAPAXI@Z 10078d06 f MSVCRTD:MSVCRTD.dll
0004:00000ad4_imp ??2@ YAPAXI @Z 100b5ad4 MSVCRTD:MSVCRTD.dll
私は削除演算子もチェックしました:
リリース:
0001:000611f0 ??3@YAXPAX@Z 100621f0 f msvcprtd:delop_s.obj
デバッグ:
0001:00077bf0 ??3@YAXPAX@Z 10078bf0 f msvcprtd:delop_s.obj
また、私はそれらのプリントアウトを持っていませんが、それが役立つ場合は入手できます。新しいオペレーターの逆アセンブリは、リリースとデバッグで同じように見えます。だから私はそれがオーバーライドではないと思いますか?演算子のインライン オーバーライドはこれを正しくないものにしますか?
また、複数の dllhost.exe プロセスを生成する COM+ アプリケーションであるため、new 演算子の呼び出しが別の DLL または exe に移動し、delete の呼び出しが反対に移動する可能性はありますか?