实际问题:
当一个程序从一个未被捕获的exception崩溃时,在Windows中会发生什么?
有没有一个DLL函数,我可以挂钩,logging一些关于崩溃的基本信息?
语境:
我正在计划编写一个程序,收集有关在本地PC上崩溃的任何应用程序的一些非常基本的信息。 我希望我可以执行一个简单的方法来logging关于崩溃的一些信息,类似于Visual Studio生成对话框的方式,让你在崩溃时debugging一个程序。
受管理的异常使用常规的Windows结构化异常处理机制来实现。 异常代码是0xe0434f4d。 Windows去寻找一个愿意处理异常的异常处理程序。 如果代码在堆栈上没有活动的try块,或者没有catch块愿意捕获托管的异常,那么托管代码中的最后一条是AppDomain.UnhandledException事件。
如果这不是执行异常处理切换到非托管处理,使用SetUnhandledExceptionFilter设置的异常过滤器得到一个镜头。 否则,总是会有一个由Windows提供的默认处理程序。 通常在调用WER,Windows错误报告程序。 这为用户提供了一个对话框来向Microsoft发送异常详细信息。 不要指望什么。
当它进展到AppDomain.UnhandledException之外时,关于托管异常的所有信息都将丢失。 没有堆栈跟踪,没有例外消息。 只是你已经知道的异常代码,以及一个你不需要使用的异常地址,因为代码是由JIT编译器动态生成的。
一定要在最后的喘息阶段捕获异常,为AppDomain.UnhandledException编写一个事件处理程序。 记录e.ExcdeptionObject.ToString()的值并使用Environment.Exit()终止程序。 还要注意Windows窗体代码中的Application.ThreadException事件和WPF代码中的Dispatcher.UnhandledException事件。 它们是在处理UI线程中的事件时引发的异常的后退停止。
对于本地应用程序,您可以使用以下功能:
此外,你可以使用AddVectoredExceptionHandler,但我不会推荐这个,因为它也拦截捕获到的异常。
传递给SetUnhandledExceptionFilter的函数指针获取一个结构作为输入参数,其中包含有关异常(reason,registers,…)的所有信息。
在我的应用程序中,我使用SetUnhandledExceptionFilter来创建应用程序转储(使用DBGHELP.DLL dll函数MiniDumpWriteDump ),如果应用程序崩溃。 小心不要在这个功能上做太多。 由于您的应用程序已经崩溃,所以不能保证任何进一步的逻辑将仍然有效(例如访问您自己的数据结构,这可能是正确的,可能会导致进一步的崩溃)。
考虑购买由John Robbins撰写的“ 调试Microsoft NET 2.0应用程序 ”一书。 我从这本书中学到了很多东西,包括这个技巧。