PinvokeStack 不平衡 MDA

Note

本文專指 .NET 框架。 此規定不適用於較新的 .NET 實作,包括 .NET 6 及更新版本。

PInvokeStackImbalance當 CLR 偵測到平台呼叫呼叫後的堆疊深度與預期堆疊深度不符時,管理除錯助理(MDA)會被啟動,前提是根據屬性中指定的DllImportAttribute呼叫慣例及受管理簽章中參數的宣告。

PInvokeStackImbalance MDA 僅實作於 32 位元 x86 平台。

Note

PInvokeStackImbalance MDA 預設是被關閉的。 在 Visual Studio 2017 及以後版本中,PInvokeStackImbalanceMDA 會出現在管理式除錯助理清單中的例外設定對話框中(選擇除錯>Windows>例外設定時會顯示)。 然而,選擇或清除「擲出時斷開」勾選框並不會啟用或停用 MDA;它只控制 Visual Studio 在 MDA 啟用時是否拋出例外。

Symptoms

應用程式在執行或執行平台呼叫時會遇到存取違規或記憶體損毀。

原因

平台調用呼叫的受管理簽章可能與被呼叫方法的未受管理簽章不符。 這種不匹配可能是因為受管理簽章未宣告正確參數數量,或未指定參數的適當大小所造成。 MDA 也可能因為調用慣例(可能由 DllImportAttribute 屬性指定)與未管理的調用慣例不符而啟動。

解決方法

檢視管理平台的 incall(signature)和呼叫慣例(call convention),確認它是否符合原生目標的簽章和呼叫慣例。 試著在管理與非管理端都明確指定呼叫慣例。 也有可能是(雖然機率較低)非管理函式因其他原因導致堆疊失衡,例如非管理編譯器的錯誤。

對運行時間的影響

強制所有平台呼叫必須走 CLR 中未優化的路徑。

Output

MDA 訊息會顯示導致堆疊不平衡的平台呼叫方法名稱。 平台呼叫方法 SampleMethod 的範例訊息如下:

呼叫 Pinvoke 函式「SampleMethod」導致堆疊失衡。 這可能是因為受管理的 PInvoke 簽章不符合非受管理的目標簽章。 檢查 PInvoke 簽名的呼叫約定和參數是否與目標非管理簽名相匹配。

Configuration

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

另請參閱