关于Windows系统里的事后调试

我一直在想,应用程序抛出未处理的异常和附加到进程的调试器之间会发生什么。显然这些信息就在我眼皮底下,但我是瞎子。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参数一起使用。如果Windows确实尝试联系内核调试器,但连接的另一端没有运行调试器,则Windows将冻结,直到激活内核调试器。在内核调试器中,可以使用gh(gowithexceptionhandled)忽略错误并继续运行目标。您可以使用gn(Go With Exception Not Handled)绕过内核调试器并继续执行步骤4。
  4. 如果步骤1、2和3中的条件不适用,Windows将激活调试工具。在这种情况下,可以预先选择任何程序作为工具。所选程序称为后期调试器。这也被称为即时调试器或JIT调试器。
    如果后期调试器是标准的用户模式调试器(如CDB、WinDbg或Microsoft Visual Studio),则此调试器将启动并进入应用程序。如果后期调试器是用于写入转储文件的工具(如Dr.Watson),则将创建内存转储文件,然后终止应用程序。
注意:如果在Windows XP或更高版本的Windows上激活Dr.Watson,则会出现一个消息框。此窗口提供向Microsoft发送错误报告的选项。如果选择不发送,将创建一个转储文件并存储在硬盘上。如果选择“发送错误报告”,将创建一个转储文件并将其存储在硬盘上,还将通过internet传输到Microsoft。
如果尚未重新配置Windows的事后调试设置,则使用Dr.Watson作为默认事后调试器。可以通过编程方式或注册表更改此设置;任何更改都会立即生效。
  • 若要将后期调试器更改为WinDbg,请运行WinDbg-I(I必须大写)。使用此命令后,将显示成功或失败消息。当WinDbg是后期调试器时,它将在应用程序崩溃时被激活。
  • 要将后期调试器更改为CDB,请运行CDB-iae或CDB-iaec键字符串。。使用-iaec开关时,key string指定要添加到AeDebug注册表项末尾的字符串。此命令成功时不显示任何消息,但失败时将显示失败消息。当CDB是后期调试器时,它将在应用程序崩溃时被激活。
  • 要将后期调试器更改为NTSD,请运行NTSD-iae或NTSD-iaec键字符串。。使用-iaec开关时,key string指定要添加到AeDebug注册表项末尾的字符串。如果键字符串包含空格,则必须用引号括起来。此命令成功时不显示任何消息,但失败时将显示失败消息。当NTSD是后期调试器时,它将在应用程序崩溃时被激活。
  • 要将后期调试器更改回Dr.Watson,请运行drwtsn32-i。当Dr.Watson是后期调试器时,如果应用程序崩溃,内存转储文件将写入磁盘。
注意:只有系统管理员才能更改后期设置。如果安装了后期调试器,则可以通过调用DebugBreak函数从用户模式应用程序中进入调试器。
 
后期调试设置存储在注册表中。如果要控制这些设置,建议您使用上述WinDbg、CDB、NTSD或Dr.Watson命令;这些命令将自动更改相关注册表项。如果确实需要手动编辑注册表,请非常小心地进行编辑,因为对注册表的不正确更改可能会导致Windows系统不可用。
在x86计算机上,后期调试设置存储在\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug。在英特尔安腾计算机上,有两个注册表项用于后期调试:
  • 64位的存储在\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug
  • 32位存储在\\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug。但是,如果此键中的调试器值指定了%windir%\system32目录中的应用程序,则Windows将改为在%windir%\syswow64中查找。
使用安腾计算机时,通常最简单的做法是在每个键中放置相同的值。特别是,如果您使用WinDbg、CDB或NTSD作为后期调试器,则安腾计算机上的32位和64位用户模式应用程序将使用相同的版本。
在这些键中应该出现两个注册表值:
  • Debugger
    此REG_SZ值指定将处理后期调试的调试器。必须列出调试器的完整路径,除非调试器位于默认路径中的目录中。
  • Auto
    此REG_SZ值始终为0或1。如果Auto设置为0,则在后期调试之前将显示一个消息框。
当出现未处理的应用程序错误时,Windows将检查是否存在DebuggerAuto注册表值。如果Auto值为0,在Windows NT和Windows 2000中,消息框将具有以下格式之一:
  • 如果Debugger的值是一个有效调试器或者是Dr.Watson,消息框会有"OK"和“Cancel”两个按钮,点击OK,应用程序将终止,点击Cancel调试器将启动。
  • 如果Debugger为空,消息框只有一个OK按钮,且不会启动调试
在Windows XP和更高版本的Windows中,消息框将具有以下格式之一:
  • 如果Debugger的值是一个有效调试器或者是Dr.Watson,消息框会有"Send Error Report"、“Don't Send”和“Debug”三个按钮,如果按下“Don't Send”按钮,则应用程序将终止。如果按下“Send Error Report”按钮,将向Microsoft发送一个小型转储文件,应用程序将终止。如果按下“Debug”按钮,将启动调试器值中指定的工具。(请注意,当“自动”值不等于0时,所有这些按钮的效果都与Dr.Watson的消息窗口上的按钮不同。)
  • 如果Debugger为空,消息框只有"Send Error Report"和“Don't Send”按钮
如果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使调试器跳过初始断点。

posted on 2019-11-19 14:44  活着的虫子  阅读(732)  评论(0编辑  收藏  举报

导航