invalidCERCall MDA
注意
本文專屬於 .NET Framework。 它不適用於較新的 .NET 實作,包括 .NET 6 和更新版本。
當方法的限制執行區域 (CER) 圖形內的呼叫沒有可靠性合約或過度弱式合約時,就會啟動 invalidCERCall
Managed 偵錯助理 (MDA)。 弱式合約是宣告最差狀態損毀範圍超過執行個體傳遞至呼叫的範圍,也就是 AppDomain 或處理序狀態可能會損毀,或在 CER 內呼叫時,其結果不一定是決定性可計算結果。
徵兆
在 CER 中執行程式碼時出現非預期的結果。 沒有特定的徵兆。 它們可能是未預期的 OutOfMemoryException、ThreadAbortException 或在呼叫不可靠的方法時發生的其他例外狀況,因為執行階段未事先準備或保護它免於執行階段的 ThreadAbortException 例外狀況。 更大的威脅就是,在執行階段因方法造成的任何例外狀況,都可能讓 AppDomain 或處理序處於不穩定的狀態,違反 CER 目標。 建立 CER 的原因是為了避免這類的狀態損毀。 損毀狀態的徵兆隨應用程式而異,因為應用程式之間的一致狀態定義各不相同。
原因
CER 中的程式碼要呼叫沒有 ReliabilityContractAttribute 的函式,或使用與 CER 中所執行者不相容之弱式 ReliabilityContractAttribute 的函式。
就可靠性合約語法而言,弱式合約是未指定 Consistency 列舉值或指定 MayCorruptProcess、MayCorruptAppDomain 或 None 之 Consistency 值的合約。 任何這些狀況都指出,呼叫的程式碼可能會阻礙 CER 中其他程式碼的工作,以維護一致的狀態。 CER 允許程式碼以非常確定的方式處理錯誤,維護對應用程式相當重要的內部非變異值,並讓它繼續在記憶體不足例外狀況等暫時性錯誤的情況下執行。
啟動此 MDA 指出在 CER 中呼叫方法,可能會因為呼叫端未預期的方式,或讓 AppDomain 或處理序保持損毀或無法修復的狀態而失敗。 當然,呼叫的程式碼可能會正確執行,而此問題只是遺漏合約。 不過,有關撰寫可靠程式碼的問題是很微妙的,缺少合約明顯表示程式碼可能不會正確執行。 合約表示程式設計人員是以可靠方式編寫程式碼,並承諾在未來修訂程式碼時也不會變更這些保證。 也就是說,合約宣告的是意圖,而不僅是實作的詳細資料。
因為任何具有弱式或不存在合約的方法,可能以許多無法預測的方式失敗,所以執行階段不會嘗試從方法中移除任何它本身無法預測的失敗;例如,從延遲的 JIT 編譯、泛型字典母體擴展或執行緒中止所導入的失敗。 亦即,啟動此 MDA 時,它會指出執行階段未包含要定義之 CER 中的呼叫方法;這個節點已終止呼叫歷程圖,因為繼續準備此子樹狀結構會幫助遮罩潛在的錯誤。
解決方法
將有效的可靠性合約新增至函式,或避免使用該函式呼叫。
對執行階段的影響
從 CER 呼叫弱式合約的效果,可能會讓 CER 無法完成其作業。 這可能會導致 AppDomain 處理序狀態損毀。
輸出
下列是來自此 MDA 的輸出範例。
Method 'MethodWithCer', while executing within a constrained execution region, makes a call at IL offset 0x000C to 'MethodWithWeakContract', which does not have a sufficiently strong reliability contract and might cause non-deterministic results.
組態
<mdaConfig>
<assistants>
<invalidCERCall />
</assistants>
</mdaConfig>