有什么我可以做的赶上AccessViolationException
?它是由我无法控制的非托管DLL引发的。是否有可能在.NET中捕获访问冲突异常?
回答
你不应该。访问冲突是一个严重的问题:这是意外的尝试写入(或读取)无效的内存地址。正如John已经阐明的那样,在引发访问冲突之前,非托管DLL可能已经损坏了进程内存。这可能对当前过程的任何部分产生不可预测的影响。
最安全的事情是可能通知用户,然后立即退出。
一些更多细节:访问冲突是一个操作系统异常(所谓的SEH或结构化异常处理异常)。这是与System.Exception
的托管CLR例外不同的例外情况。您很少会在纯粹的托管代码中看到SEH异常,但是如果出现这种异常,例如在非托管代码中,CLR会将其交给托管代码,您也可以在其中捕获它。
然而,捕SEH异常大多不是一个好主意。进一步的细节在MSDN杂志文章Handling Corrupted State Exceptions在下面的文本从采取的解释:使用相同的机制,通过程序本身引起的异常
的CLR一贯提供的SEH例外托管代码。只要代码不尝试处理无法合理处理的异常情况,这就不成问题。访问冲突后,大多数程序无法安全地继续执行。不幸的是,CLR的异常处理模型一直鼓励用户通过允许程序捕获System.Exception层次结构顶部的任何异常来捕获这些严重错误。但这很少是正确的。
这是真的,直到.NET 3.5。在.NET 4中,行为已经改变。如果您仍然希望能够捕捉到这种异常情况,则必须将legacyCorruptedStateExceptionsPolicy=true
添加到app.config。上面链接的进一步细节。
您可以使用try-catch块将调用包装为非托管DLL。 AccessViolationExceptions可以正常抓到。执行以下代码显示了两个消息:
try
{
throw new AccessViolationException();
}
catch (Exception e)
{
MessageBox.Show(e.Message + e.StackTrace, e.Message, MessageBoxButtons.OK, MessageBoxIcons.Error);
}
MessageBox.Show("Still running..");
编辑: .NET 4中引入的一个change in behavior,它不再可能赶上损坏状态的异常,除非您特别"ask"运行时这样做。
首先我用0xA3执行完全ACK。但是,如果没有出路,你可以将脏的非托管DLL包装在自己的进程中,并通过IPC(TCP/IP,namedpipes等)传输数据。捕获所有异常并通知主机进程。所以你的主机进程主要是从内存损坏中保存。
是。
在你的应用程序。CONFG,扑通的<configuration>
标记中下面的代码:
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
现在,你应该能够赶上损坏的状态异常(CSE)像任何其他。
注意:如果你已经有一个运行时的标签,然后简单地添加<legacyCorruptedStateExceptionsPolicy enabled="true"/>
它
上述作品.NET 4.5
为此。我读了几个关于这个问题的答案。所有人都说“将'legacyCorruptedStateExceptionsPolicy enabled =”true“/>'添加到'app.config'”,但没有人说这不应该在默认的“
正如其他人指出的那样,你不应该“处理”这一条件,但在开发过程中,为了排除故障,很方便。
您可以标记与System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions
属性的管理方法:
[HandleProcessCorruptedStateExceptions]
public void MyMethod()
{
try
{
NaughtyCall();
}
catch (AccessViolationException e)
{
// You should really terminate your application here
}
}
- 1. 访问冲突异常applicationbar
- 2. 访问冲突异常C#
- 3. C++异常访问冲突
- 4. 访问冲突异常
- 5. 访问冲突异常
- 6. UWP访问冲突异常
- 7. 异常访问冲突Java?
- 8. 访问冲突异常
- 9. JNI异常访问冲突
- 10. 访问冲突异常
- 11. 访问BackStack时访问冲突异常
- 12. 是否有可能在java中捕获致命的xml异常?
- 13. 是否有可能捕获net :: ERR_BLOCKED_BY_CLIENT?
- 14. 是否有可能在JavaScript中捕获财产访问权限?
- 15. NullReference异常后收到访问冲突异常(0xc0000005)是否正常
- 16. 什么可能导致此异常访问冲突?
- 17. 是否有可能使用aspectj捕获所有异常?
- 18. 是否有可能在纯托管代码中生成/产生c0000005访问冲突异常?
- 19. 是否有可能捕获除运行时异常外的所有异常?
- 20. 捕获(...)是否能捕获所有异常?
- 21. 无法捕获访问冲突
- 22. CreateDibSection抛出访问冲突异常
- 23. Boost Asio tcp :: acceptor访问冲突异常
- 24. 访问冲突异常emguCV cvQueryHistValue
- 25. boost :: spirit :: qi和访问冲突异常
- 26. Form.FormBorderStyle原生异常访问冲突
- 27. Qt C++读取访问冲突异常
- 28. C++ msvcp90d.dll访问冲突异常
- 29. new int []抛出'访问冲突'异常
- 30. 是否有可能检测到按值捕获异常切片?
澄清:您希望退出ASAP的原因是,您不知道非托管DLL在达到访问冲突之前被覆盖的内容。它可能在足够的地方编写垃圾,导致程序无法安全地继续。 – 2010-07-22 18:38:55
@John Saunders:谢谢你的澄清。我更新了我的答案。 – 2010-07-22 18:47:31
我可以想到一个非常好的理由来解决这个问题:如果你有一个无人管理的进程,而你没有这个进程,而不是退出,那么这个进程将会挂起,访问冲突对话框会显示没有人。捕捉它可让您在没有弹出对话框的情况下退出。 – jpwkeeper 2013-05-16 14:09:48