CIL:“操作によりランタイムが不安定になる可能性があります”例外

StackOverflow https://stackoverflow.com/questions/615530

質問

PostSharpを少し使ってみましたが、厄介な問題に遭遇しました。

SilverlightアセンブリのILに従う:

.method public hidebysig specialname newslot virtual final instance void 
set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
    .maxstack 2
    .locals (
        [0] bool ~propertyHasChanged,
        [1] bool CS$4
public void set_AccountProfileModifiedAt(DateTime value)
{
    bool propertyHasChanged = this.AccountProfileModifiedAt != value;
    this.accountProfileModifiedAt = value;
    if (propertyHasChanged)
    {
        this.NotifyPropertyChanged("AccountProfileModifiedAt");
    }
}
) L_0000: nop L_0001: nop L_0002: ldarg.0 L_0003: call instance valuetype [mscorlib]System.DateTime Accounts.AccountOwner::get_AccountProfileModifiedAt() L_0008: ldarg.1 L_0009: call bool [mscorlib]System.DateTime::op_Inequality(valuetype [mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime) L_000e: stloc.0 L_000f: ldarg.0 L_0010: ldarg.1 L_0011: stfld valuetype [mscorlib]System.DateTime Accounts.AccountOwner::accountProfileModifiedAt L_0016: br.s L_0018 L_0018: ldloc.0 L_0019: ldc.i4.0 L_001a: ceq L_001c: stloc.1 L_001d: ldloc.1 L_001e: brtrue.s L_002b L_0020: ldarg.0 L_0021: ldstr "AccountProfileModifiedAt" L_0026: call instance void Accounts.AccountOwner::NotifyPropertyChanged(string) L_002b: nop L_002c: leave.s L_002e L_002e: ret }

トリガーSystem.Security.VerificationException:操作によりランタイムが不安定になる可能性があります。例外。 Reflectorはそれを解析します。何が問題なのでしょうか?

更新1 コードは次のように機能することを目的としています。

L_0018: ldloc.0 
L_0019: ldc.i4.0 
L_001a: ceq 
L_001c: stloc.1 
L_001d: ldloc.1 

更新2 セッター自体の内部で指定された例外を受け取ります

更新3 callvirt(NotifyPropertyChanged)として非静的呼び出しを行うことは役に立ちません

更新4 (テスト目的の)コードのコメントアウト:

.method public hidebysig specialname newslot virtual final instance void 

set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
    .maxstack 2
    .locals init (
        [0] bool val,
        [1] bool CS$4<*>)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: call instance valuetype [mscorlib]System.DateTime 

Accounts.AccountOwner::get_AccountProfileModifiedAt()
    L_0007: ldarg.1 
    L_0008: call bool [mscorlib]System.DateTime::op_Inequality(valuetype 

[mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime)
    L_000d: stloc.0 
    L_000e: ldarg.0 
    L_000f: ldarg.1 
    L_0010: stfld valuetype [mscorlib]System.DateTime 

Accounts.AccountOwner::accountProfileModifiedAt
    L_0015: ldloc.0 
    L_0016: ldc.i4.0 
    L_0017: ceq 
    L_0019: stloc.1 
    L_001a: ldloc.1 
    L_001b: brtrue.s L_0029
    L_001d: ldarg.0 
    L_001e: ldstr "AccountProfileModifiedAt"
    L_0023: call instance void 

Accounts.AccountOwner::NotifyPropertyChanged(string)
    L_0028: nop 
    L_0029: ret 
}

L_001e:brtrue.s L_002bをL_001e:br.s L_002bに置き換えると、トリックを実行できますが、無条件に戻ります-私が望むものではありません。

アップデート5 C#コンパイラを使用して必要な動作を模倣する場合(Postsharpでそれを行う必要があります) 次のILを取得します。

<*>

小さな違いがあることに注意してください-L_0016での追加のbr.sジャンプといくつかの奇妙なジャンプL_001e:brtrue.s L_002b。コンパイラバージョンでは、retに直接ジャンプします。

役に立ちましたか?

解決

peverifyを使用しましたか? MSILを直接使用する場合は、常にこのユーティリティを実行する必要があります(msbuildフラグ/ p:PostSharpVerify = trueを使用できます)。

コードを見る:

  1. ローカル変数は初期化されていません(&quot; init&quot;キーワードがありません)。これは、MethodBodyDeclarationのプロパティです。

  2. 保護ブロックから「jmp」の代わりに「leave」を使用しています。これは役に立ちませんが、問題ではありません。

幸運を祈ります

-gael

他のヒント

言うのは難しい-スタックトレースはありますか?この例外は通常、CLRがコードの型安全性を検証できない場合にスローされます。これはこのコードまたは使用しているメソッドまたはタイプのいずれかから発生した可能性があるため、スタックトレースなしで問題が何であるかを言うのは困難です。

こちらは、そのエラーを扱った投稿です。あなたの特定のケースが同じ問題によって引き起こされているかどうかはわかりませんが、一般的にこれはコードアクセスのセキュリティと検証に関係しているようです。その場合、ReflectorはILを正常に読み取ることができますが、CASシステムは未知の理由でそれを追い出します。

他の多くのオブジェクトを呼び出すプロパティセッターがあるようです。ポストで言及されている特定の問題の場合は、大きなswitchステートメントを探して他のメソッド呼び出しを実行する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top