注意:本文中中断指break。
控制异常和事件
Debugger可以有很多方法来处理在用户态或者是内核态程序中的异常。事后调试,active调试等都是一些常用处理异常的方法。
当windows允许调试器来处理异常,程序会生成一个异常break,之后调试器就可以进行调试。调试器能够进行一些操作来进行现场分析。之后可以终止进程或者是恢复执行。
当调试器忽略掉这个异常并让程序继续执行,Windows会寻找其他存在的异常处理器。如果异常被处理,程序就会被继续执行。但是如果异常仍然是未处理状态,调试器就会获得第二次调试机会。
Using the Debugger to Analyze an Exception
使用调试器来分析异常。当异常中断调试器时就可以使用调试起来调试code。就可以修改一些变量或者是跳到另一个地方执行从而去除掉异常的原因。
可以通过命令 gh(Go with Exception Handled)或者gn(Go with Exception Not Handled)命令来恢复执行。
如果在第二次中断机会时使用了gn命令,则程序将退出。
Kernel-Mode Exceptions
内核态异常的严重程序要高于用户态异常。如果内异常没有被处理,则会引起系统BSOD。
和用户态异常一样,如果内核态调试器在调试系统,则会在BSOD之前收到中断。如果没有调试器则会直接BSOD,之后则可能声称一个dump文件。
Controlling Exceptions and Events from the Debugger
可以通过配置调试器来响应指定的异常和事件。
调试器可以为下面几种异常和事件设置中断状态:
- 能够在事件发生时让调试器终端的的第一次调试机会
- 能够在其他错误处理器处理之后来响应的事件,即第二次调试机会。
- 发送信息给调试器,但是会继续执行的事件
- 调试器能够忽略的事件
调试器能够设置每个异常和事件的处理状态,从而让调试器可以把这些事件当作是处理过的事件或者未处理的事件。
可以通过下面几种方式来控制中断状态和处理状态:
- windbg使用SXE, SXD, SXN, SXI命令
- windbg中的Event Filter中设置相应的一场或事件。
SX\*命令可以设置中断状态。可以通过-h 选项来设置处理状态。
共有4中特殊的event状态(cc, hc, bpec, ssec)总是指定处理状态而不是中断状态。
可以使用.lasteven命令来显示最近的异常和事件。
Controlling Break Status
当设置异常和事件的中断状态时,可以使用如下选项:
SXE or -xe
Break
(Enabled)
当该异常发生时,目标机会立即中断,调试器会先于其他处理器收到该事件。也被称作第一次调试机会。.
SXD or -xd
Second chance break
(Disabled)
调试器不会被该事件中断,不过仍然会显示该事件的信息。如果其他处理器不能够处理该异常,则调试器仍然会被中断。这被称为第二次调试机会。
SXN or -xn
Output
(Notify)
当这个异常发生时调试器不会被中断,但是会显示信息。
SXI or -xi
Ignore
当异常发生时不会中断,也不会显示信息。
如果异常不在SX*设置里,目标程序会在第二次机会时中断调试器。
设置中断状态也可以使用windbg中Filters来设置。可以设置四种状态 Enabled, Disabled, Output 和Ignore。
Controlling Handling Status
如果不使用命令gh来进行设置处理状态,则所有的事件都会被认为是未处理的。
异常也一样,如果不使用sx\*加上-h来设置,则所有异常都被认为是未处理的。
另外SX*选项可以设置无效句柄的处理状态,STATUS_BREAKPOPINT指令和单步异常。这些事件名为ch,bpe,sse。而配置处理状态时他们的事件名为hc,bpec和ssec。
也可以设置CTRL+C的处理状态,名称为cc。但是不能设置他的中断状态。如果程序收到了一个CTRL+C的事件就将永远会被调试器中断。
当使用SX*命令设置cc,hc,hc,bpec和ssec或者使用SX*加-h时将会发生一下操作
SXE | Handled | 当中断继续执行时,事件将被认为时已经处理。 |
SXD,SXN,SXI | Not Handled | 继续时该事件被当作未处理。 |
也可以使用Windbg Event Filters来设置处理状态。
Automatic Commands
Windbg也提供自动执行命令的能力,允许用户设定一些命令将会在异常或者是事件到来时被调试器自动执行。可以使用SX\*来设置。如果像设置多个命令,可以使用分号分隔。
无论中断状态如何,这些命令都会被执行。即便中断状态为Ignore命令也都会被执行。
Event Definitions and Defaults
你可以设置下列的异常的中断状态和处理状态。下面也列出了中断状态的默认值,而默认处理状态都是未处理,他们的处理状态要小心,因为如果设置了他们的处理状态为handled则所有第一次或第二次调试机会都会被认为是处理过的,就会导致该异常会跳过所有的异常处理例程。
asrt | Assertion failure | Break |
av | Access violation | Break |
dm | Data misaligned | Break |
dz | Integer division by zero | Break |
c000008e | Floating point division by zero | Break |
eh | C++ EH exception | Second-chance break |
gp | Guard page violation | Break |
ii | Illegal instruction | Second-chance break |
iov | Integer overflow | Break |
ip | 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 This exception is triggered if the Windows operating system concludes that a process has stopped responding (that is, is hung). | Break |
3c | Child application termination | Second-chance break |
chhc | Invalid handle | Break |
Number | Any numbered exception | Second-chance break |
注意:可以通过ah重写指定一个地址的asrt中断状态。ch和hc事件码指的一样的异常。可以使用sx* ch改变中断状态,使用sx* hc来改变处理状态。
可以改变下列异常的中断状态和处理状态。
以下所有的异常的默认处理状态都是处理过的。因为这些异常被用来和调试器沟通,不应该随意修改他们的处理状态为未处理过的状态。如果windbg忽略了这鞋异常,这个状态会引起其他的异常处理器来捕获这些异常。
程序能够使用DBG_COMMAND_EXCEPTION(dbce)来和调试器通信。异常类似于断点,但是可以使用SX*命令来对异常发生做出不同的反应。
dbce | Special debugger command exception | Ignore |
vcpp | Special Visual C++ exception | Ignore |
wos | WOW64 single-step exception | Break |
wob | WOW64 breakpoint exception- | Break |
sse | Single-step exception | Break |
bpe | Breakpoint exception | Break |
cce | CTRL+C or CTRL+BREAK This exception is triggered if the target is a console application and CTRL+C or CTRL+BREAK is passed to it. | Break |
注意:最后三个异常有两个不同的事件名。sse,bpe,cce用来控制中断状态。ssec,bpec,cc用来控制处理状态。
The following exceptions are useful when you are debugging managed code.
clr | Common Language Runtime exception | Second-chance break Not handled |
clrn | Common Language Runtime notification exception | Second-chance break Handled |
可以通过下面的事件来改变中断状态。这些事件不是异常,因此他们的处理状态不重要。
ser | System error | Ignore |
cpr[:Process] | Process creation Setting the break status of this event applies only to user-mode debugging. This event does not occur in kernel mode. You can control this event only if you have activated debugging of child processes in CDB or WinDbg, either through the -ocommand-line option or through the .childdbg (Debug Child Processes) command. The process name can include an optional file name extension and an asterisk () or question mark (?) as wildcard characters. The debugger remembers only the most recent cpr setting. Separate settings for separate processes are not supported. Include a colon or a space between cpr and Process. If Process is omitted, the setting applies to any child process creation. | Ignore |
epr[:Process] | Process exit Setting the break status of this event applies only to user-mode debugging. This event does not occur in kernel mode. You can control this event only if you have activated debugging of child processes in CDB or WinDbg, either through the -ocommand-line option or through the .childdbg (Debug Child Processes) command. The process name can include an optional file name extension and an asterisk () or question mark (?) as wildcard characters. The debugger remembers only the most recent epr setting. Separate settings for separate processes are not supported. Include a colon or a space between epr and Process. If Process is omitted, the setting applies to any child process exit. | Ignore |
ct | Thread creation | Ignore |
et | Thread exit | Ignore |
ld[:Module] | Load module If you specify Module, the break occurs when the module with this name is loaded. Module can specify the name or the address of the module. If the name is used, Module might contain a variety of wildcard characters and specifiers. (For more information about the syntax, see String Wildcard Syntax.) The debugger remembers only the most recent ld setting. Separate settings for separate modules are not supported. Include a colon or a space between ld and Module. If Module is omitted, the event is triggered when any module is loaded. | Output |
ud[:Module] | Unload module If you specify Module, the break occurs when the module with this name, or at this base address, is unloaded. Module can specify the name or the address of the module. If the name is used, Module can be an exact name or include wildcard characters. If Module is an exact name, it is immediately resolved to a base address by using the current debugger module list and it is stored as an address. If Module contains wildcard characters, the pattern string is kept for later matching when unload events occur. Rarely, the debugger does not have name information for unload events and matches only by the base address. Therefore, if Module contains wildcard characters, the debugger cannot perform a name match in this particular unload case and breaks when any module is unloaded. The debugger remembers only the most recent ud setting. Separate settings for separate modules are not supported. Include a colon or a space between ud and Module. If Module is omitted, the event is triggered when any module is loaded. | Output |
out[:Output] | Target application output If you specify Output, the break occurs only when output that matches the specified pattern is received. Output can contain a variety of wildcard characters and specifiers. (For more information about the syntax, see String Wildcard Syntax.) However, Output cannot contain a colon or spaces. The match is not case sensitive. Include a colon or space between out and Output. | Ignore |
ibp | Initial break point (This event occurs at the beginning of the debug session and after you restart the target computer.) | In user mode: Break. You can change this status to "Ignore" by using the -gcommand-line option. In kernel mode: Ignore. You can change this status to "Enabled" by a variety of methods. For more information about how to change this status, see Crashing and Rebooting the Target Computer. |
iml | Initial module load (Kernel mode only) | Ignore. You can change this status to "Break" by a variety of methods. For more information about how to change this status, see Crashing and Rebooting the Target Computer. |