我使用框架.NET 4.5.1在我的应用程序中获得了一个损坏的状态异常(CSE)。从事件查看器获取的此异常是:
框架版本:v4.0.30319
描述:由于.NET运行时在IP 000007FEEB8F75CB(000007FEEB7B0000)中出现内部错误而导致进程终止,退出代码为80131506.
我使用问题How to simulate a corrupt state exception in .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对问题Gracefully handling corrupted state exceptions的响应中所讨论的那样。
但我无法用它来捕捉这个错误。为什么?
适用于使用以下内容生成的访问冲突:
private static unsafe void AccessViolation()
{
byte b = *(byte*) (8762765876);
}
执行我记录错误消息的处理程序的代码但当然,我没有得到与我的应用程序相同的错误。
更新:
我尝试通过复制this issue中描述的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();
我重复它只是为了调试。目标是找到在更大的应用程序中出现此错误类型的代码部分,以便进行修复。