从调试器控制异常和事件:SXE、 SXD、 SXN、SXI

来源:互联网 发布:疯狂的美工助手要钱吗 编辑:程序博客网 时间:2024/04/27 20:58

控制异常和事件

在用户模式和内核模式应用程序中有很多方法用于截获和处理异常。激活的调试器、即时调试器或内部的错误处理程序都是异常处理的通常方法。

关于这些错误处理方式优先等级的更多信息,查看启用即时调试。

当Microsoft Windows操作系统允许由调试器来处理异常时,产生异常的程序会中断到调试器。即应用程序停止运行而调试器被激活。之后,调试器可以用各种方式处理掉异常或者分析情况。最后,调试器可以结束进程或恢复它的执行。

如果调试器跳过异常并继续程序执行,操作系统如同没有附加调试器一样会查找其他异常处理器。如果异常被处理掉,则程序继续运行。但是,如果异常仍然没有处理,系统会给予调试器第二次处理机会。

使用调试器分析异常

当异常或事件中断到调试器时,可以用调试器检查被执行的代码或者查看进程内存。通过修改某些值或者跳转到程序的另一个位置,可能可以解决掉这个异常。

使用gh (Go with Exception Handled) 或 gn (Go with Exception Not Handled) 命令恢复程序执行。

如果在调试器的第二次异常处理机会时使用gn 命令,则程序被终止。

内核模式异常

内核模式代码产生的异常比用户模式异常要更加严重。如果内核模式异常没有被处理,则会产生bug check并且系统停止。

和用户模式异常一样,如果有内核调试器附加到系统上,在错误检查屏幕(即蓝屏)产生前,会先通知调试器。如果没有附加调试器,则直接蓝屏。这种情况下,系统可能会创建崩溃转储文件。

从调试器控制异常和事件

可以设置调试器处理异常和事件的方式。

调试器可以为每个异常或事件设置中断方式

  • 事件发生时直接中断到调试器("第一次处理机会")。
  • 在其他错误处理器已经接收到处理机会之后。("第二次处理机会")。
  • 在发生事件时发送一条信息到调试器,但是继续执行。
  • 调试器跳过事件。

调试器也可以为每个异常和事件设置处理方式。调试器可以将事件当作已处理异常或未处理异常来对待。(当然,并不是实际出错的事件是不需要处理的。)

可以用如下方法来控制中断方式和处理方式:

  • 在调试器命令窗口使用SXE、 SXD、 SXNSXI 命令。
  • (仅CDB)在CDB 命令行中使用-x、 -xe-xd-xn-xi 选项。
  • (仅CDB) 在Tools.ini 文件中使用sxe 或 sxd 关键字。
  • (仅WinDbg) 在Debug菜单点击 Event Filters 打开Event Filters 对话框,并进行需要的配置。

SX*命令、-x* 命令行选项和sx* Tools.ini 关键字用于设置特定事件的中断方式。添加-h 选项来设置事件的处理方式。

有4个特殊的事件代码(cchcbpec, 和ssec)只能指定处理方式。

使用.lastevent (Display Last Event) 命令显示最近一次异常或事件。

控制中断方式

为异常或事件设置中断方式可以使用以下选项。

命令

条件名

说明

SXE

-xe

Break

(Enabled)

当异常发生时,目标立即中断到调试器。该中断在其他任何错误处理器被调用之前。这种方法称为第一次异常处理

SXD

-xd

Second chance break

(Disabled)

调试器不会在第一次异常处理机会时中断(虽然会显示一条信息)。如果其他错误处理其不能处理异常,则目标停止执行并中断到调试器。这种方法称为第二次异常处理

SXN

-xn

Output

(Notify)

当异常产生时,目标应用程序不会中断到调试器。但是,调试器中会显示一条有关的信息。

SXI

-xi

Ignore

异常发生时,目标程序不会中断带调试器,并且不会显示信息。

 

如果某个异常预先没有使用SX* 设置过,则目标进程在第二次机会时中断到调试器。所有事件的默认方式在下面的"事件定义和默认设置"主题中列出。

使用WinDbg图形界面设置中断方式,可以在Debug菜单打开Event Filters ,并在Event Filters 对话框中点击要设置的事件,并选择EnabledDisabledOutputIgnore

控制处理方式

除非使用gh (Go with Exception Handled) 命令,否则所有事件都不会被处理。

所有异常都不会被处理,除非使用了sx* 命令和-h选项。

另外,SX* 选项可以配置非法句柄、STATUS_BREAKPOINT 中断指令和单步异常的处理方式。 (这个配置和他们的中断配置是分开的。)配置中断方式时,这些事件分别名为 chbpesse。在配置异常处理方式时,他们分别名为hcbpecssec (完整的事件列表,查看下面的"事件定义和默认设置"节。)

CTRL+C 事件(cc)可以配置处理方式,但是没有中断方式。如果程序接收到了CTRL+C事件,总是会中断到调试器。

当为cc、 hc、 bpec和 ssec 事件使用SX*命令,或对某个异常将SX* 和-h 选项一起使用时,会遇到下面一些情况。

命令

方式

说明

SXE

Handled

重新开始执行时事件已被处理。

SXD,
SXN,
SXI

Not Handled

重新开始执行时事件未被处理。

 

使用WinDbg图形界面设置中断方式,可以在Debug菜单打开Event Filters ,并在Event Filters 对话框中点击要设置的事件,并选择Handled 或Not Handled

自动命令

调试器允许设置一些命令用于当事件或异常中断到调试器时自动执行。可以分别为第一次异常处理和第二次异常处理设置一个命令字符串。使用SX* 命令或Debug | Event Filters 菜单命令设置。每个命令字符串可以包含用分号隔开的数条命令。

不管中断方式如何,这些命令都会被执行。换句话说,即使中断方式为"Ignore",命令仍然会被执行。如果中断方式为"第二次处理机会",则第一次处理机会的命令在异常第一次发生时,调用任何其他处理程序前被执行。命令字符串可以以运行命令结尾,如g (Go)gh (Go with Exception Handled)gn (Go with Exception Not Handled)

事件定义和默认设置

可以修改以下这些异常的中断方式和处理方式。下表同时指明了他们的默认中断方式。

以下异常的默认处理方式都是"Not Handled"。修改这些方式时要特别小心。如果将方式修改为"Handled",则所有第一次异常和第二次异常都被认为是已处理,原有的所有异常处理函数都会被跳过。

事件代码

含义

默认中断方式

asrt

断言错误(Assertion failure)

中断(Break)

av

访问违例(Access violation)

Break

dm

数据未对齐(Data misaligned)

Break

dz

除零(Divide by zero)

Break

eh

C++ EH异常(C++ EH exception)

Second-chance break

gp

页保护违例(Guard page violation)

Break

ii

非法指令(Illegal instruction)

Second-chance break

iov

整数溢出(Integer overflow)

Break

ip

页面I/O错误(In-page I/O error)

Break

isc

非法系统调用(Invalid system call)

Break

lsq

非法加锁次序(Invalid lock sequence)

Break

sbo

栈缓冲区溢出(Stack buffer overflow)

Break

sov

栈溢出(Stack overflow)

Break

wkd

唤醒调试器(Wake debugger)

Break

aph

应用程序挂起(Application hang)

这个异常在Windows操作系统结束停止相应的进程时触发(即挂起)。

Break

3c

子程序终止(Child application termination)

Second-chance break

ch
hc

非法句柄(Invalid handle)

Break

Number

所有编号的异常(Any numbered exception)

Second-chance break

 

注意  可以使用ah (Assertion Handling)命令覆盖指定地址的asrt 中断方式。ch 和hc 事件是同一个异常。控制中断方式时,使用sx* ch;控制异常处理方式时,使用sx* hc

可以修改以下这些异常的中断方式和处理方式。下表同时指明了他们的默认中断方式。

以下异常的默认处理方式都是"Handled"。由于这些异常是用来和调试器通信的,所以一般不能把它们设置为"Not Handled",否则调试器会跳过这些异常并由其他异常处理器来处理。

应用程序可以使用DBG_COMMAND_EXCEPTION (dbce) 来和调试器通信。这个异常类似断点,但是可以使用SX*命令来指定该异常发生时的对待方式。

事件代码

含义

默认中断方式

dbce

专用调试器命令异常(Special debugger command exception)

跳过(Ignore)

vcpp

专用Virtual C++异常(Special Visual C++ exception)

Ignore

wos

WOW64单步异常(WOW64 single-step exception)

Break

wob

WOW64断点异常(WOW64 breakpoint exception)

Break

sse
ssec

单步异常(Single-step exception)

Break

bpe
bpec

断点异常(Breakpoint exception)

Break

cce
cc

CTRL+C 或CTRL+BREAK

当目标程序是控制台程序并输入了CTRL+C或CTRL+BREAK。

Break

 

注意  上表中最后三个异常有两个不同的事件代码。控制中断方式时,使用 ssebpe, 和cce。控制异常处理方式时,使用ssecbpec和 cc

可以修改下面这些事件的中断方式。由于他们不是异常,所以和异常处理方式无关。

事件代码

含义

默认中断方式

ser

系统错误(System error)

Ignore

cpr[:Process]

创建进程(Process creation)

当通过CDB的-o 命令行选项或 WinDbg .childdbg (Debug Child Processes) 命令启用子进程调试时,该事件才可控制。进程名可以包含任意扩展名和星号(*)、问号(?)通配符。

Ignore

epr[:Process]

进程退出(Process exit)

当通过CDB的-o 命令行选项或 WinDbg .childdbg (Debug Child Processes) 命令启用子进程调试时,该事件才可控制。进程名可以包含任意扩展名和星号(*)、问号(?)通配符。

Ignore

ct

线程创建(Thread creation)

Ignore

et

线程退出(Thread exit)

Ignore

ld[:Module]

加载模块(Load module

如果指定了Module,则当名字为指定值的模块加载时发生中断。如果没有指定Module,任何模块加载时都会中断。调试器只会记录最近一次的ld设置。不支持对多个模块多次设置。Module可以指定模块的名字或地址。如果指定名字,Module可以包含通配符和说明。(关于该语法的更多信息,查看字符串通配符语法。) 在ldModule之间需要加上一个冒号或者空格。

输出(Output)

ud[:Module]

卸载模块(Unload module) 

如果指定了Module,则当名字为指定值的模块加载时发生中断。如果没有指定Module,任何模块加载时都会中断。调试器只会记录最近一次的ud设置。不支持对多个模块多次设置。Module可以指定模块的精确名字或地址。如果Module是精确名字,调试器会使用保存的模块列表和地址将它立即转换为地址来记录。如果Module包含通配符,则字符串模板会被保存下来在之后的卸载事件发生时用来匹配。

极少数情况下,调试器在卸载事件发生时有地址匹配的模块,但是没有它的模块名信息。因此,如果Module 包含通配符,这种情况下调试器无法确定被卸载模块的名字,所以任何模块被卸载都会中断。在udModule之间需要加上一个冒号或空格。

Output

out[:Output]

目标程序输出(Target application output

如果指定了Output,仅当接收到和模板字符串匹配的输出时才中断。Output 可以包含数个通配符和说明。 (关于该语法的更多信息,查看字符串通配符语法。) 但是,Output中不能包含冒号或者空格。匹配不是大小写敏感的。在outOutput之间应该加上一个冒号或者空格。

Ignore

ibp

初始断点(Initial break point)

(该事件在开始调试会话和重起目标机时发生。)

用户模式:Break。可以使用-g 命令行选项将这个方式修改为"Ignore" 

内核模式:Ignore 。可以通过几种方法设置为"Enabled" 关于修改该方式的更多信息,查看崩溃和重起目标机。

iml

初始模块加载(Initial module load)

(仅内核模式)

Ignore。可以通过几种方法设置为"Break" 关于修改该方式的更多信息,查看崩溃和重起目标机。

0 0
原创粉丝点击