CIL:“操作可能会破坏运行时间”例外 [英] CIL: "Operation could destabilize the runtime" exception

查看:115
本文介绍了CIL:“操作可能会破坏运行时间”例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩PostSharp,遇到一个令人讨厌的问题。

I've been playing with PostSharp a bit and I ran into a nasty problem.

在Silverlight装配中遵循IL:

Following IL in Silverlight assembly:

.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$0000)
    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解析为OK。

triggers System.Security.VerificationException: Operation could destabilize the runtime. exception. Reflector parses it OK. What could be wrong with it?

更新1
代码的作用如下:

Update 1 Code is intended to work as follows:

public void set_AccountProfileModifiedAt(DateTime value)
{
    bool propertyHasChanged = this.AccountProfileModifiedAt != value;
    this.accountProfileModifiedAt = value;
    if (propertyHasChanged)
    {
        this.NotifyPropertyChanged("AccountProfileModifiedAt");
    }
}

更新2
我在setter本身内部得到了指定的异常

Update 2 I get specified exception inside the setter itself

更新3
以callvirt(NotifyPropertyChanged)进行非静态调用不会帮助

Update 3 Making non-static calls as callvirt (NotifyPropertyChanged) does not help

更新4
注释掉(出于测试目的)代码:

Update 4 Commenting out (for test purposes) code:

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_001e:br.s L_002b可以解决问题但这是无条件的返回-不是我想要的。

and replacing L_001e: brtrue.s L_002b with L_001e: br.s L_002b does the trick but it's an unconditional return - not what I want.

Update 5
如果我使用C#编译器模仿所需的行为(我仍然需要使用Postsharp来做到这一点)
我得到以下IL:

Update 5 If I use C# compiler to mimic required behavior (I still need to do that with Postsharp) I get following IL:

.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$0000)
    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 
}

请注意,两者之间存在细微差别-额外的br.s跳至L_0016还有一些奇怪的跳转L_001e:brtrue.s L_002b。在编译器版本中,我可以直接跳转至ret。

Note there are minor differences - extra br.s jump at L_0016 and some strange jump L_001e: brtrue.s L_002b. In compiler version I get direct jump to ret.

推荐答案

您使用过peverify吗?直接与MSIL一起播放时,应该始终运行此实用程序(可以使用msbuild标志/ p:PostSharpVerify = true)。

Did you use peverify? You should always run this utility when playing directly with MSIL (you can use the msbuild flag /p:PostSharpVerify=true).

查看代码:


  1. 您的局部变量未初始化(缺少 init关键字)。这是MethodBodyDeclaration的属性。

  1. Your local variables are not initialized (missing "init" keyword). This is a property of MethodBodyDeclaration.

您在受保护的块中使用的是离开而不是 jmp;

You are using a 'leave' instead of a 'jmp' out of a protected block; this is useless but should not matter.

祝你好运,

-gael

这篇关于CIL:“操作可能会破坏运行时间”例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆