前言:对于Debug模式程序的调试,大家都比较熟悉。但对于Release模式下程序异常崩溃,很多程序员束手无策。其实,Release模式的发布程序,通过一些方法也可以获取程序崩溃时的堆栈信息,并可以生成Dump文件。此后的几篇文章将介绍这些方法。这些方法大多为网络上查找的,本人只是做一个总结。文章从基础开始谈起,没有任何Release除错经验的人也可以完全看明白。
本文将介绍以下三个方面的内容:
1、 Windows错误处理流程
2、 调试工具包
3、 drwtsn32简介
一、 Windows错误处理流程
当 Windows 中出现程序错误时,系统将搜索错误处理程序。程序错误处理程序处理程序运行过程中出现的错误。如果系统找不到程序错误处理程序,系统将验证是否该程序当前没有被调试,并认为错误没有被处理。然后系统通过在“注册表编辑器”中查找程序错误调试程序来处理尚未处理的错误。
系统在“注册表编辑器”(通过命令regedit 进入)的注册表项:
//HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/AeDebug
下查找名为 Debugger 和 Auto 的项。Debugger 项的值指定了调试程序将要用来分析程序错误的命令。如果找到了调试程序项的值,系统将查看 Auto 项的值是设置为 0 还是 1。
l 如果 Auto 项的值设置为 0,系统将产生一个消息框,通知您发生了程序错误。如果“调试程序”项的值指定了有效调试程序所使用的命令,消息框将显示两个按钮:“确定”和“取消”。如果单击“确定”,程序将终止。如果单击“取消”,系统将启动指定的调试程序。如果“调试程序”项的值为空,消息框将只显示“确定”,并且不启动任何调试程序。
l 如果 Auto 项的值设置为 1,并且调试程序项的值指定了有效调试程序所使用的命令,系统将自动启动该调试程序,并且不会产生消息框。
当在系统上安装 Windows 时,默认情况下 Auto 项的值设置为 1,并且调试程序项的值指定了启动 Dr.Watson 的命令。这意味着当出现程序错误时,Dr.Watson for Windows 将自动诊断错误,并记录相应的诊断信息。
如果您使用的默认调试程序不是 Dr.Watson,而又要换用 Dr.Watson,请在命令提示符后键入命令 drwtsn32 -i 来启动Dr.Watson。键入 -i 可对注册表进行必要的更改。
Windows下的调试工具有很多,比如drwtsn32、NTSD、KD、CDB、WinDbg等。
二、 调试工具
1、 本系列文章中所使用的调试工具,可以通过URL:
http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.11.1.404.msi 下载,这是一个x86系统32位的调试工具包,如果需要其他环境的工具包,可以在同级目录中寻找。
2、 下载安装后,可以将安装后的文件拷贝到所需要的目录。比如将Debugger键值设置为C:/WINDOWS/system32/ntsd.exe -p %ld -e %ld -g -c ".dump D:/Dump/jit.dmp;q",则需要将安装目录中的ntsd.exe拷贝到C:/WINDOWS/system32/目录中,如果存在ntsd.exe,选择覆盖,即将最新版本的调试工具覆盖之前的版本。
三、 drwtsn32简介
1、 安装 Windows 时,会将 Dr.Watson (Drwtsn32.exe) 安装到系统文件夹中。首次运行 Dr.Watson 时(即出现程序错误时或用户亲自启动 Dr.Watson 时),会设置默认选项。Dr.Watson for Windows 是一个程序错误调试程序。Dr.Watson 记录的信息是技术支持小组诊断运行 Windows 的计算机的程序错误所需的信息。只要检测到错误,就会创建一个文本文件 (Drwtsn32.log),并可按支持人员常用的方式传递给支持人员。也可以选择创建故障转储文件,它是程序员可以加载到调试程序中的二进制文件。如果出现程序错误,Dr.Watson 将自动启动。
图1.1 Dr. Watson界面
通过界面可以对Dr.Watson进行参数配置。
图1.2 默认的注册表项设置
2、 当程序异常退出时,系统通过注册表找到drwtsn32程序,根据配置将生成调试信息。打开Drwtsn32.log可以查看程序崩溃时的堆栈等信息。另外转储生成的dmp格式文件为二进制文件,可以通过各种调试软件打开,并分析程序错误。
图1.3 log 格式文件格式
错误提示对话框一般显示为:
图1.4 Drwtsn32错误提示对话框
3、 drwtsn32 参数意义
drwtsn32 [-i] [-g] [-p pid] [-e event] [-?]
-i 将 DrWtsn32 当作默认应用程序错误调试程序
-g 被忽略,但作为 WINDBG 和 NTSD 的兼容而被提供
-p pid 要调试的进程 id
-e event 表示进程附加完成的事件
-? 这个屏幕
4、 drwtsn32缺点
1) Dr. Watson cannot debug applications that are running under non-administrative accounts (e.g. it cannot debug applications running under LocalService and NetworkService accounts). In brief, it happens because when kernel32! UnhandledExceptionFilter function calls CreateProcess to start just-in-time debugger (Dr. Watson in this case), it forces the debugger process to attach to WinSta0 window station and WinSta0/Default desktop. By default, only LocalSystem account and members of Administrators group have access to these objects, all other user accounts cannot access them. As a result, any application that uses windows (I mean User objects) or console cannot operate properly and fails in early startup phase.
运行时对运行帐号有要求
2) Dr. Watson cannot send notifications over network (and thus does not provide a way for us to get notified when an application crashes on a remote system).
在程序崩溃时,不能发送通告
3) Dr. Watson cannot create crash dump files with unique names (it always uses the file name specified in its settings, and every subsequent debugging session will overwrite the old crash dump file with the new one). As a result, we can lose an important crash dump if another application happens to crash before we have managed to copy the dump file into a safe location.
User.dmp文件不能取不同的文件名,如果另外一个程序死机,之前生成的user.dmp将被覆盖
4) There is a limited choice of crash dump formats. On Windows NT 4.0 and Windows 2000, only one crash dump format is available (so called “full user dump”). Windows XP and Windows Server 2003 support two additional formats(standard minidump and minidump with full memory contents). If you read my Effective Minidumps article, you already know that better choices of minidump formats often exist.
格式受限制,Windows XP和Windows Server 2003支持另外的两种格式