如果你的程序在客户的机器上崩溃了,那么你现在可以使用 minidumps 和 Microsoft Visual Studio .NET 调试器在事后进行调试。本文讲述了 minidumps 是怎样工作的、当你的程序崩溃的时候应该如何生成它们、以及如何在 Visual Studio .NET 中将它们重新读入。微软的错误报告程序之所以能够改进 Windows 操作系统和诸如 Visual Studio .NET 这样的应用程序的稳定性,其关键就在于 minidumps。本文也讲述了如何使用 Microsoft 符号服务器自动地为系统组件查找符号。你在阅读本文前应该已经熟悉 Win32 和 C++ 编程了。
它们所包含的内容并不都是有用的。事实上,Dr.Watson 是一个 just-in-time(JIT)调试器,但调试器很难得到一个已加载模块的完整路径。完整的调试器,例如 Visual Studio 调试器,为了获得这些路径进行了很多额外的工作,但是 Dr.Watson 却没有。这通常就会导致毫无意义的模块名,如 MOD0000 等等。
Minidumps 在设计时就使用了几个方法用来解决上述问题:
只有几个区域被保存下来,而不是整个进程空间。保存诸如 Kernel32.dll 这样的模块简直毫无意义;只要给出了版本号,就可以很容易地从一张 Windows CD 上拿到这个文件。默认情况下,程序的内存堆是不保存的;不需要调试一个崩溃比率高得令人乍舌的崩溃点。当然,如果你想的话,还是可以把堆保存下来的。
现在,你需要找到一张 Windows 操作系统的 CD 或者已经安装了正确版本的机器,然后将所需要的文件复制到一个目录。通常情况下没有必要把进程中每个模块的二进制文件都找出来,但是找出那些在每个调用栈上的关键模块是很重要的。这通常包括操作系统的二进制文件(例如 Kernel32.dll)和你自己的二进制模块(在这个例子中就是 Notepad.exe)。
一个找系统符号的好地方在 http://www.microsoft.com/ddk/debugging,你也可以在 Windows NT Server 和 Windows 2000 Server 操作系统的 Support CD 上找到系统符号。在本例中,它们被拷贝到了二进制代码所在的位置。实际情况中你可能会遇到非微软发布的二进制模块,这时候你就需要它们的 PDB 文件了。同样在本例中,Notepad 的 DBG 和 PDB 文件也被拷贝了出来,因为它是我们使用的样本应用程序。
微软使用 minidumps 改进其程序的历史已经有一年多了(本文发布于 2002 年 3 月 7 日——译者注)。Microsoft Internet Explorer 5.5 和 Microsoft Office XP 是第一批与新版的 Dr.Watson 同时发布的产品。这个新版的 Dr.Watson 可以在程序停止响应时捕获程序中未处理的异常,创建一个 minidump,然后询问用户是否愿意将信息提交给微软。
进一步改进
在服务器端,可以根据发生崩溃的组件和崩溃点对 minidumps 进行分析和归类,这样就可以使产品组得到程序的崩溃频率、以及某个崩溃情况的发生频率,小组也可以得到崩溃时的 minidumps 以便日后分析。在某些情况下,如果崩溃的原因已经完全查明,则用户可以被引导到一个网页,这个页面上有已知的、可以暂时避免这种崩溃的方法,或者一个解决该问题的补丁。在 Internet Explorer 5.5 和 Office XP 发布后,有很多其他产品组已经开始使用类似的技术收集崩溃信息了。它同时也是 Windows XP 的一个标准部分。
另外,如果在一个 Windows 服务中遇到了未处理的异常,那么为它创建 minidumps 将是另一个挑战。你需要处理桌面访问(例如,如果没有人在使用控制台,那么你就无法提示他们)以及安全上下文。
总结
Minidumps 是一种新技术,它使得程序在用户的机器上崩溃后也可以进行事后调试。向已有的程序中加入代码、使其在遇到未捕获的异常时自动创建 minidumps 也是一件很容易的事。Visual Studio .NET 可以很容易地载入它们,从而重现崩溃现场、使得开发人员可以调试程序。符号服务器可以很轻松地找到系统符号文件,帮助分析。
附:版权及免责声明
本文的原文(英文)版权归原作者 Andy Pennell 所有。原作者并没有授权 Victor 进行本文的中文翻译工作,所以本文并不是原文的中文版本。译者 Victor 不对原文、译文及译文注释中可能出现的任何错误以及可能由其带来的任何损失(直接或间接)承担任何法律责任,包括但不限于技术错误、翻译错误、语法错误、拼写错误等。Victor 保留本文的版权,但 Victor 允许其他个人或单位在不得到 Victor 本人书面同意的情况下进行非商业目的且仅限于非商业目的的转载且仅限于在互联网上转载,但相应的转载说明中必须包括本文的原始出处、英文版作者名 Andy Pennell、译者名 Victor 以及原文链接。任何转载行为必须包含本版权及免责声明,否则因此而引起的一切纠纷由转载者负责。