3

大規模な MFC ベースのアプリをヒープ破損エラーでクラッシュさせるテスト ケースがあります。

問題の DLL に対して App Verifier を使用してページ ヒープを有効にしました (プロセス全体でヒープを有効にすることは、残念ながら他の理由で実行できません)。元のクラッシュと同じ時点でトリガーされました。

現在、私は2つの競合する理論を持っています。どちらの理論が正しい可能性が高いと思いますか?次のステップは何ですか?

  1. これは確かにヒープの破損です。別の DLL で発生しているため、ベリファイアは元の損傷を検出していません。より多くの DLL に対してベリファイアをアクティブ化し、どのコードがヒープを損傷しているかを特定する必要があります。
  2. ヒープは問題ありません。問題は、スタック アドレスをヒープ アドレスとして扱っていることです。このコールスタックのコードをさらに調べて、何が問題なのかを突き止める必要があります。

free() へのパラメーターがスタック アドレスのように見えるため、私は #2 に傾いていますが、これがどのように可能であるかについて、これまでのところ誰も説明を提案していません。

コール スタックのスニペットを次に示します。MyString は、CString の単純なラッパーです。MyAppDll は、ページ ヒープを使用するように設定された DLL です。

msvcr90.dll!free(void * pBlock=0x000000000012d6e8) 110行目
mfc90u.dll!ATL::CStringT > >::~CStringT > >() 行 1011 + 0x1e バイト
MyStringDll.dll!MyString::~MyString() 59行目
MyAppDll.dll!doStuffWithLotsOfStringInlining(MyClass* 入力=0x000000000012d6d0) 行 863 + 0x26 バイト

free() スタック フレーム内のレジスタは次のとおりです。

RAX = 0000000000000000 RBX = 000000000012D6E8 RCX = 0000000000000000
RDX = 0000000000000000 RSI = 000000000012D6D0 RDI = 00000000253C1090
R8 = 0000000000000000 R9 = 0000000000000000 R10 = 0000000000000000
R11 = 0000000000000000 R12 = 000000000012D7D0 R13 = 000007FFFFC04CE0
R14 = 0000000025196600 R15 = 0000000000000000 RIP = 00000000725BC7BC
RSP = 000000000012D570 RBP = 000007FFF3670900 EFL = 00000000

アプリ検証メッセージは次のとおりです。

VERIFIER STOP 0000000000000010: pid 0x1778: ヒープ ブロックの開始スタンプが破損しています。

    00000000083B1000 : 呼び出しで使用されるヒープ ハンドル。
    000000006DD394E8 : 操作に関与するヒープ ブロック。
    54D32858A8747589 : ヒープ ブロックのサイズ。
    000000005E33BA8D : スタンプ値が壊れています。
4

1 に答える 1

2

あなたの文字列またはそのユーザーは、文字列のバッファのどこかでオーバーフロー/アンダーフローしていると思います。おそらく、文字列ポインタの隣にあるフィールドに対して、解放しようとしています。

あなたの RSP は 12D570 で、これは解放しようとしているものから 94 クワッド (int) 離れているため、その間のどこかでバッファに問題が発生しています。

安全でない文字列操作を行っていないこと、および使用している DLL にバッファー/文字列を渡すためのドキュメントを正しく読んでいることを確認してください。

より正確な回答が必要な場合は、質問にさらにコードが必要になる可能性があります。

于 2011-02-17T23:23:46.763 に答える