1

C++ アプリで COM を介して呼び出している C# ライブラリ モジュールでヒープ破損エラーが発生します。具体的なエラーは次のとおりです。

ヒープ: 解放された後、4b61be8 で変更されたヒープ ブロック 4b61bb8 を解放し
ます...
これは、ヒープの破損が原因である可能性があり、[app].exe またはそれがロードした DLL のバグを示しています。

コール スタックのトップは次のとおりです。

CustomMarshalers.dll!System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext() + 0x168 bytes

私の理解では、.NET はメモリの問題を軽減するものであり、メモリの問題を修正不可能にするものではないということでした。それでも、メモリエラーを引き起こすために何をしているのか、またはそれを修正しようとしている方法は考えられません。特定のモジュールは、Microsoft.VisualStudio.VCProjectEngine .NET コンポーネントを使用して、非常に単純な反復子で VC プロジェクト ファイルを反復処理しています。以前の約 100 回の呼び出しに成功した後、VCProject フィルター (フォルダー) でファイルを反復処理しているときに、foreach ステートメントで中断しています。壊れている実際のコードは次のとおりです。

    IVCCollection CollectionFiles = (IVCCollection)FolderInProject.Files;
    foreach (VCFile File in CollectionFiles)
    {
        [...]
    }

どうすればこれをデバッグできますか?

アップデート:

純粋な C# コンソール アプリ (COM やネイティブ コードを含まない) から if を呼び出すと、次のようになります。

タイプ 'System.AccessViolationException' の未処理の例外が [component].dll で発生しました

追加情報: 保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています。

これをデバッグする方法はまだわかりません。明らかに、どこかでメモリ エラーが発生しています...しかし、メモリ モデルが公開されていない純粋なマネージ コードでそれを追跡するにはどうすればよいでしょうか?

4

1 に答える 1

1

COM インターフェイスがパラメーター/戻り変数を適切にマーシャリングしていないようです。GC によってマネージド メモリが予期せず解放されるか、不適切なマーシャリングが原因でアンマネージド メモリが破棄されます。COM コンポーネント用の独自のPrimary Interop Assemblyを構築することによって作成された COM インターフェイスをより細かく制御できます。少しの作業で、COM オブジェクトの問題のあるメソッドを調べ、そのすべてのパラメーターに正しいメタデータが含まれていることを確認して、それらが正しくマーシャリングされていることを確認できます。

もう 1 つの可能性は、すべてを適切にマーシャリングしているが、インターフェイスを正しく呼び出していないことです。これは、最終的に管理されていないメモリを破壊するパラメーターの不適切な使用として現れます。特に COM ソースにアクセスできない場合は、これらを追跡するのはあまり楽しくありません。

1 つのトリックは、プログラムがデバッガーの外部でクラッシュできるようにすることです。[デバッグ] をクリックすると、[JIT デバッガーの選択] ウィンドウが表示されます。次に、[Choose Debugging Engine] (またはその効果のあるもの) をチェックし、[Managed] チェックボックスと [Native] チェックボックスの両方がチェックされていることを確認します。発生する VS インスタンスは、死に最も近いマネージ コードではなく、実際に死んだコードで壊れている必要があります。

于 2008-10-10T02:42:26.607 に答える