【问题标题】:WinDbg single step exception not firingWinDbg 单步异常未触发
【发布时间】:2015-01-19 02:01:33
【问题描述】:

我正在 WinDbg 中调试一个 exe (x86),因为它在我的计算机上崩溃,开发人员不提供支持并且它是封闭源代码。

到目前为止,我发现它崩溃是因为将空指针传递给ntdll!RtlEnterCriticalSection

我试图找到那个空指针的来源,我已经到达了一个点(我的“当前点”),我完全不知道它是从哪里调用的。我尝试搜索堆栈上最后几个地址的区域,但那里根本没有调用、跳转或返回。

我唯一拥有的是崩溃前加载的最后一个 dll,这显然在我当前点之前也很长(至少几千条指令)。

我不能只设置几千个断点,所以我认为单步异常会有所帮助(我至少可以在每条指令上打印eip,我不在乎这是否需要几天时间)。

但我无法让 CPU 触发异常!加载exe后,我在调试器中输入以下内容:

sxe ld:<dll name>
g
sxe sse
sxe wos
r tf=1
g

调试器在我想要的位置中断加载的 dll,但在第二个 g 之后,程序在到达崩溃点之前只运行了几秒钟,根本没有引发任何单步异常。

如果我在没有前两行的情况下做同样的事情(所以我在程序的起点),它可以工作。我知道每次触发 SSE 时,tf 都会设置为零,但为什么在程序的后期它根本不触发呢?

我错过了什么吗?或者有没有其他方法可以找到那个空指针的来源?

【问题讨论】:

  • 你试过 kv 命令在崩溃时列出堆栈和参数吗?
  • @KjellGunnar 当然,但由于它打印了一些地址和符号,它还向我提供了警告 WARNING: Stack unwind information not available. Following frames may be wrong. 我一直在使用 kd
  • 你的目标是什么?调查没有符号和源代码的第 3 方代码中的错误是徒劳的。即使你发现了问题,你也无法为它编写一个有意义的修复程序。我的建议是您在 WinDbg 中使用命令.dump -ma 创建故障转储并将其发送给产品所有者。故障转储应该足以让他们找到并解决问题。
  • 好吧,我想你是对的。明天会这样做,只是希望开发人员足够关心。但这仍然不能解释为什么单步异常没有触发,我有点想知道,只是因为我很好奇......
  • 很有可能(我在这里假设)命令g 自动设置tf=0,因为它意味着继续执行程序直到下一个断点。这就是命令t 的用途——它在当前线程上下文中设置tf=1

标签: exception windbg breakpoints


【解决方案1】:

g 不是单步命令,它的意思是“go”,只在断点或异常处中断。

要执行单步,请使用p。由于您没有源代码,因此您无法在源代码级别进行指令步进,这意味着您必须在汇编级别进行。 (汇编程序指令步进应该是默认的,它不会通过l-t 启用它。)根据您需要走多远,这需要时间。

以上仅按原样回答问题。悬而未决的问题是,就像 cmets 中已经指出的那样,您将采取什么措施来减轻该错误?您不能简单地创建一个新的临界区,也不知道应该在那个地方使用哪个现有的临界区。

【讨论】:

  • 由于该程序可以在大多数计算机上运行,​​但在其他一些计算机上崩溃(包括我的)我假设有代码可以在某处实例化关键部分,但该代码根本失败(或由于以下原因而被跳过一个失败的断言,基本相同)。如果是这种情况,我希望找出导致失败的确切原因,我怀疑这是未记录的软件依赖关系或未记录的驱动程序/硬件不兼容。无论如何,这回答了最初的问题,谢谢。
猜你喜欢
  • 2018-02-16
  • 1970-01-01
  • 2019-07-10
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 2016-04-25
相关资源
最近更新 更多