我在使用框架 .NET 4.5.1 的应用程序中收到损坏状态异常 (CSE)。从事件查看器获取的这个异常是:
框架版本:v4.0.30319
说明:由于 IP 000007FEEB8F75CB (000007FEEB7B0000) 处的 .NET 运行时中的内部错误,该进程已终止,退出代码为 80131506。
我通过使用问题如何在 .NET 4 中模拟损坏状态异常?:
using System;
using System.Runtime.InteropServices;
class Program {
unsafe static void Main(string[] args)
{
var obj = new byte[1];
var pin = GCHandle.Alloc(obj, GCHandleType.Pinned);
byte* p = (byte*)pin.AddrOfPinnedObject();
for (int ix = 0; ix < 256; ++ix) *p-- = 0;
GC.Collect(); // kaboom
}
}
我在事件 UnhandledException 的处理程序上使用属性 HandleProcessCorruptedStateExceptions 和 SecurityCritical ,如 haindl 对问题优雅处理损坏状态异常的响应中所述。
但我无法用它捕捉到这个错误。为什么 ?
这适用于生成的访问冲突:
private static unsafe void AccessViolation()
{
byte b = *(byte*) (8762765876);
}
执行我记录错误消息的处理程序的代码,但当然,我没有收到与我的应用程序中相同的错误。
更新:
我试图通过重现此问题中描述的 3 个步骤来捕获 CSE :
重新编译为 .NET 3.5 程序集并在 .NET 4.0 中运行。
在配置/运行时元素下的应用程序配置文件中添加一行:
使用 HandleProcessCorruptedStateExceptions 属性装饰您想要捕获这些异常的方法。有关详细信息,请参阅 http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035。
但这对我不起作用!
我的代码是:
using System;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Test
{
class Program
{
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
static void Main(string[] args)
{
while (true)
{
try
{
PerformException();
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
}
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
unsafe static void PerformException()
{
var obj = new byte[1];
var pin = GCHandle.Alloc(obj, GCHandleType.Pinned);
byte* p = (byte*)pin.AddrOfPinnedObject();
for (int ix = 0; ix < 256; ++ix) *p-- = 0;
GC.Collect(); // CSE occurs here.
}
}
}
我的 app.config 文件是:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
</configuration>
为什么 CSE 没有被抓到?
注意我必须允许代码以不安全模式构建,因为以下行代码需要它:
byte* p = (byte*)pin.AddrOfPinnedObject();
我再说一遍,它只是为了调试。目标是在更大的应用程序中找到发生此错误类型的代码部分,以便进行修复。