Debugging Tools for Windows

启用即时调试

大多数公共的应用程序错误称为异常。包括访问违例、除零、数字溢出和一些其他种类的错误。

应用程序也可能产生断点中断。当Windows不能继续运行程序(例如必须的模块不能加载)或者当遇到断点的时候会产生。断点可以由调试器插入代码中,也可以通过对类似DbgBreakPoint这样的函数调用产生。在汇编语言中,断点一般由int 3指令产生。

Windows可以通过各种方式处理用户模式错误。下面按优先顺序列出了错误处理方式:

  1. 如果出错进程已经附加上了用户模式调试器,所有错误都会使得目标中断到调试器。

    在用户模式调试器已经附加上去的时候,不会再使用其他错误处理方法,即使使用了gn (Go With Exception Not Handled)命令。

  2. 如果没有附加调试器并且执行的代码有自己的异常处理程序(例如try - except),异常处理程序会被尝试用于处理错误。
  3. 如果没有用户模式调试器附加,并且Windows打开了内核调试连接,并且错误是一个断点中断,Windows会尝试联络内核调试器。

    内核调试连接必须在Windows引导过程中就打开。如果运行Windows Server 2003或之后的Windows,并且希望避免从用户模式中断到内核调试器,可以使用KDbgCtrl 实用工具和-du参数。关于如何配置内核调试连接及如何使用KDbgCtrl,查看配置目标机的软件

    如果Windows尝试联系内核调试器,但是在连接的另一端没有调试器运行,Windows会停止并等待内核调试器激活。

    在内核调试器中,可以使用gh (Go With Exception Handled)来忽略错误并继续运行目标。使用了gn (Go With Exception Not Handled)命令来跳过内核调试器并进入第4步。

  4. 如果上面1、2、3步骤的条件都不满足,Windows将激活一个调试工具。任何程序都可以将自己设置为在这种情况下使用的工具。被选定的程序称为即时调试器。也称为just-in-time 调试器或者JIT调试器

    如果即时调试器是标准的用户模式调试器(如CDB、WinDbg或者Microsoft Visual Studio),该调试器会被启动起来并且中断应用程序。

    如果即时调试器是用于创建dump文件的工具(如Dr. Watson),将会创建一个内存转储(dump)文件,并且应用程序将被终止。

注意 如果Dr. Watson 在Windows XP或之后版本Windows中被激活,会出现一个消息框。这个窗口提供选项来发送错误报告给Microsoft。如果选择不发送(Don't Send),一个dump文件会被创建并保存到磁盘中。如果选择发送错误报告,dump文件会被创建并保存,同时将通过网络发送给Microsoft。

如果没有重新配置过即时调试设置,默认的即时调试器是Dr. Watson 。这个设置可以通过编程或者注册表修改,并且立即生效。

只有系统管理员可以修改即时调试设置。

如果安装了即时调试器,用户模式应用程序可以通过调用DebugBreak 函数来主动中断到调试器中。

编辑注册表

即时调试设置被保存在注册表中。如果想控制这些设置,推荐使用上面描述过的WinDbg、CDB、NTSD或Dr. Watson 命令;他们将会自动修改相应的注册表键。如果要自己修改注册表,注意要非常小心,对注册表的不合适修改会造成Windows不能使用。

在x86计算机上,即时调试设置保存在 \\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug 键。

在Intel Itanium计算机上,有两个用于即时调试的注册表键:

  1. 出错的64位应用程序会根据保存在 \\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug 中的键来调试。
  2. 出错的32位应用程序会根据保存在 \\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug 键中的内容来调试。但是,如果该键的Debugger键值 指定了%windir%\system32 目录中的程序,Windows将会在%windir%\syswow64 中查找它。

当使用Itanium计算机时,通常简单的为这些键指定相同的值。特别的,如果使用WinDbg、CDB或NTSD作为即时调试器,在Itanium计算机上32位和64位用户模式程序都会使用同一个版本的调试器。查看选择32位或64位调试器包获取更多信息。

这些键中可能出现的键值有两个:

Debugger
这个REG_SZ 值指定用于进行即时调试的调试器。必须列出调试器的全路径,除非调试器在默认路径下。
Auto
这个REG_SZ值总是0或者1 。如果Auto 设置为0,在即时调试器打开前会先显示一个消息框。

当应用程序产生未处理的异常时,Windows检查是否DebuggerAuto键值存在。

如果Auto 值为0,会出现一个消息框。

在Windows 2000中,这个消息框会是下面的格式之一:

在Windows XP和之后的Windows中,消息框会是下面格式之一:

如果Auto 值为1,不会出现消息框。Debugger 值中指定的调试器会自动启动。

注册表示例

下面的键值用于设置Dr. Watson 为即时调试器(这是默认情况):

Debugger = "drwtsn32 -p %ld -e %ld -g"
Auto = 1

下面的值设置WinDbg为即时调试器:

Debugger = "Path\WinDbg -p %ld -e %ld"
Auto = 1

下面的值设置CDB为即时调试器

Debugger = "Path\CDB -p %ld -e %ld -g"
Auto = 1

在这些例子中,Path 是调试器所在的目录,-p %ld 指定被调试的进程ID,-e %ld 提供造成异常的事件,-g 使得调试器跳过初始断点。 (Dr. Watson 跳过 -g 选项。)

安全漏洞

如果想要在公用计算机上使用即时调试,查看即时调试的安全性

Build machine: CAPEBUILD