首页 > 解决方案 > windbg StopOnException 的“伪寄存器号”参数有什么作用?

问题描述

这是 windbg 命令的帮助文本StopOnExceptionsoe简称):

0:000> !soe
usage: StopOnException [-derived] [-create | -create2] <type name>
                       [<pseudo-register number for result>]
ex:    StopOnException -create System.OutOfMemoryException 1

结果的伪寄存器号”参数是什么?该示例使用该值1,但没有任何后续操作。

我能找到的唯一其他文档就是这样说的:

StopOnException [-derived] [-create | -create2] <Exception> <Pseudo-register number>  

使调试器在引发指定异常时停止,但在引发其他异常时继续运行。

-derived 选项捕获指定的异常以及从指定异常派生的每个异常。

...文中根本没有提到这个论点。该页面上也没有任何其他使用“伪”一词,或具有相同含义的“注册”。

标签: windbg

解决方案


windbg 中有额外的帮助文本可以解释它。我花了一段时间才意识到这一点,也许它对windbg的新手有用:

 0:000> !help stoponexception

产生:

 !StopOnException [-derived] 
                  [-create | -create2] 
                  <Exception> 
                  [<Pseudo-register number>]

!StopOnException 在您希望 Windows 调试器停止特定托管异常(例如 System.OutOfMemoryException)时很有帮助,但如果引发其他异常则继续运行。该命令可以通过两种方式使用:

  1. 当您只想停止一个特定的 CLR 异常时

    在调试器提示符处,加载 SOS 后的任何时间,键入:

    !StopOnException -创建 System.OutOfMemoryException 1

    伪寄存器编号 (1) 表示 SOS 可以使用寄存器 $t1 来维护断点。-create 参数允许 SOS 继续并将断点设置为第一次机会异常。-create2 会将其设置为第二次机会异常。

  2. 当您需要更复杂的逻辑来停止 CLR 异常时

    !StopOnException 可以纯粹用作更大表达式中的谓词。如果您键入:

    !StopOnException System.OutOfMemoryException 3

    如果当前线程上最后抛出的异常是 System.OutOfMemoryException,那么寄存器$t3 将设置为 1。否则,$t3 将设置为 0。使用 Windows 调试器脚本语言,您可以将此类调用链接在一起以停止各种异常类型。您必须手动创建此类谓词,例如:

    sxe -c "!soe System.OutOfMemoryException 3; !soe 派生的 System.IOException 4; .if(@$t3==1 || @$t4==1) { .echo 'stop' } .else {g} "

-derived 选项将导致 StopOnException 将 伪寄存器设置为 1,即使抛出的异常类型与给定的异常类型不完全匹配,而只是从它派生。因此,“-derived System.Exception”将捕获 System.Exception 层次结构中的每个异常。

伪寄存器号是可选的。如果不传递数字,SOS 将使用伪寄存器$t1。

我强调了相关部分。

本质上,此选项允许您指定应使用哪个伪寄存器来跟踪断点。也许在某些情况下,如果您不想覆盖现有的重要值,指定您自己的寄存器选择可以避免这种情况。

有关伪寄存器值的更多信息: https ://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/pseudo-register-syntax


推荐阅读