次の方法で共有


PInvokeStackImbalance MDA

Note

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

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

PInvokeStackImbalance MDA は 32 ビット x86 プラットフォームに対してのみ実装されています。

Note

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

現象

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

原因

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

解決方法

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

ランタイムへの影響

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

出力

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

PInvoke 関数 'SampleMethod' に対する呼び出しによってスタックが不安定になっています。 PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。 呼び出し規約、および PInvoke シグネチャのパラメーターがターゲットのアンマネージ シグネチャに一致していることを確認してください。

構成

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

関連項目