PInvokeStackImbalance MDA

Note

この記事は .NET Framework に固有のものです。 .NET 6 以降のバージョンを含む、.NET の新しい実装には適用されません。

PInvokeStackImbalanceマネージド デバッグ アシスタント (MDA) は、プラットフォーム呼び出しの呼び出し後のスタック深度が、DllImportAttribute属性で指定された呼び出し規則とマネージド 署名内のパラメーターの宣言によって予期されるスタック深度と一致しないことを CLR が検出するとアクティブになります。

PInvokeStackImbalance MDA は、32 ビット x86 プラットフォームでのみ実装されます。

Note

PInvokeStackImbalance MDA は既定で無効になっています。 Visual Studio 2017 以降のバージョンでは、PInvokeStackImbalance MDA が [例外設定] ダイアログ ボックスの [マネージド デバッグ アシスタント] の一覧に表示されます ([デバッグ>Windows>Exception 設定] を選択すると表示されます)。 ただし、[スローされたときに中断] チェック ボックスをオンまたはオフにしても、MDA は有効または無効になりません。MDA がアクティブ化されたときにVisual Studioが例外をスローするかどうかを制御するだけです。

Symptoms

プラットフォーム呼び出しの呼び出しを行ったり、呼び出しを実行したりすると、アプリケーションでアクセス違反またはメモリの破損が発生します。

原因

プラットフォーム呼び出し呼び出しのマネージド シグネチャが、呼び出されるメソッドのアンマネージド シグネチャと一致しない可能性があります。 この不一致は、マネージド シグネチャで正しい数のパラメーターが宣言されていないか、パラメーターに適切なサイズが指定されていないことが原因で発生する可能性があります。 また、 DllImportAttribute 属性で指定されている呼び出し規約がアンマネージ呼び出し規則と一致しないため、MDA をアクティブにすることもできます。

Resolution

マネージド プラットフォームの呼び出し署名と呼び出し規則を確認して、ネイティブ ターゲットの署名と呼び出し規則と一致することを確認します。 マネージド側とアンマネージド 側の両方で呼び出し規則を明示的に指定してみてください。 アンマネージド コンパイラのバグなど、何らかの理由でアンマネージド関数がスタックを不均衡にしている可能性もあります。

ランタイムへの影響

すべてのプラットフォーム呼び出しが CLR で最適化されていないパスを取得するように強制します。

アウトプット

MDA メッセージは、スタックの不均衡の原因となっているプラットフォーム呼び出しメソッド呼び出しの名前を示します。 メソッド SampleMethod のプラットフォーム呼び出し呼び出しのサンプル メッセージは次のとおりです。

PInvoke 関数 'SampleMethod' の呼び出しによってスタックが不均衡になっています。 これは、マネージド PInvoke シグネチャがアンマネージド ターゲット シグネチャと一致しないことが原因である可能性があります。 PInvoke シグネチャの呼び出し規則とパラメーターが、ターゲットのアンマネージド シグネチャと一致することを確認します。

コンフィギュレーション

<mdaConfig>
  <assistants>
    <pInvokeStackImbalance />
  </assistants>
</mdaConfig>

こちらも参照ください