通过订阅AppDomain.Current.Domain UnhandledException事件,我的.net应用程序具有全局异常处理程序。在少数情况下,我看到我的应用程序崩溃,但这个全局异常处理程序从未命中。不确定它是否有帮助,但应用程序正在执行一些COM互操作。
我的理解是,只要我没有任何局部catch块吞噬异常,这个全局异常处理程序就应该总是被命中。我可能遗漏了什么,导致这个处理程序从未被调用?
发布于 2011-03-14 03:12:09
在捕获非托管代码可能导致的所有异常方面,CLR并不是万能的。通常是AccessViolationException btw。只有当从托管代码调用非托管代码时,它才能捕获它们。不支持的方案是非托管代码启动自己的线程,而此线程会导致崩溃。当您使用COM组件时,这并不是非常不可能。
从.NET 4.0开始,致命的执行引擎异常不再导致触发UnhandledException事件。该异常被认为太糟糕,不允许运行更多的托管代码。它是。传统上,StackOverflowException会导致立即中止。
您可以从流程的ExitCode中对此进行某种程度上的诊断。它包含终止进程的异常的异常代码。0x8013yyyy是由托管代码引起的异常。0xc0000005是访问冲突。等等。您可以使用adplus (可从Windows调试工具下载中获得)来捕获进程的一个小转储。由于这可能是由COM组件引起的,因此与供应商合作可能对解决此问题很重要。
发布于 2011-03-14 00:44:40
发布于 2011-03-14 04:03:54
由于您正在执行COM互操作,因此我强烈怀疑某些非托管代码正在另一个线程中运行,这确实导致了未处理的异常。这将导致应用程序退出,而不调用未处理的异常处理程序。除此之外,在.NET 4.0中,当应用程序在没有进一步通知的情况下关闭时,该策略确实会变得更强。在以下情况下,您的应用程序将在没有进一步通知的情况下关闭(Environmnt.FailFast)。
Pre .NET 4:
.NET 4:
您可以通过使用HandleProcessCorruptedStateExceptionsAttribute修饰方法来覆盖.NET 4中的行为,也可以将legacyCorruptedStateExceptionsPolicy标记添加到App.config中。
如果您的问题是非托管代码中的未捕获异常,则可以在调试器下运行应用程序,或者让它崩溃并收集内存转储以进行事后调试。调试崩溃转储通常是使用WindDbg完成的。下载Windbg后,您可以将adplus (位于Programm Files\ due for Windows下的vbs脚本)附加到正在运行的进程,以便在进程因异常而终止时触发崩溃转储。
adplus -crash -p您的进程-p
然后,您将有更好的机会了解进程终止时发生的情况。Windows还可以配置为在旧版本上通过DrWatson为您获取崩溃转储(Windows错误报告)
崩溃转储生成
核心程序员将坚持创建他们自己的转储生成工具,该工具基本上使用AEDebug注册表键。当此键具有指向现有可执行文件的值时,它将在应用程序崩溃时调用,例如,显示Visual Studio调试器选择器对话框,或者它可以触发进程的转储生成。
挂起线程
经常被忽视的一件事是,当您使用外部工具创建崩溃转储时(最好依靠外部工具,因为您不知道您的进程被损坏的程度有多严重,如果它耗尽了内存,那么您已经处于一个糟糕的情况),您应该在进行转储之前挂起崩溃进程中的所有线程。当您进行一个大型的完全内存转储时,可能需要几分钟的时间,具体取决于出错进程的内存分配情况。在此期间,应用程序线程可能会继续破坏您的应用程序状态,留下一个包含不一致进程状态的转储,该状态在转储生成过程中发生了变化。
https://stackoverflow.com/questions/5290747
复制相似问题