【问题标题】:Windbg break-in takes very long timeWindbg磨合需要很长时间
【发布时间】:2017-06-17 13:18:22
【问题描述】:

我想捕获有时会停止响应几分钟的应用程序的堆栈跟踪。

当应用程序停止响应时,windows 桌面也停止响应鼠标点击,虽然其他一些已经在运行的应用程序在那个时候工作正常(例如 windbg 工作正常,ProcessExplorer 刷新它的屏幕,但不响应鼠标事件)。 虽然应用程序没有响应,但它实际上占用了一个 CPU 内核的 80% 左右。这就是我想要获取堆栈跟踪的原因。

行为不端的应用程序通常需要大约 2-3 分钟才能完成其奇怪的工作,或者如果按下 Ctrl+Esc,它会立即响应(当然,开始菜单也会打开......)

我已将 WinDbg 附加到行为异常的应用程序,当我发出中断命令时,在应用程序再次开始响应之前不会发生闯入。

据我了解,入侵实际上创建了一个远程线程,该线程很快就会调用DbgBreakPoint

什么可能阻止调试器的线程执行?

编辑: 首先感谢您的帮助!

我还认为这可能是由于设备驱动程序错误或在某处安装了系统范围的挂钩造成的。

我正在考虑启用内核调试并从内核获取违规线程的堆栈跟踪,或者启用手动蓝屏触发器以产生转储并在之后查看。

Process Explorer 和 Process Monitor 没有发现任何有趣的东西。当错误被触发时,它们也会变得不可用(更新它们的窗口但不响应鼠标或键盘)。

EDIT2: 背景资料: 应用程序使用 QT、OpenGL 和 DirectSound 并在 Windows 7 SP1 x64 上运行 我目前怀疑图形部分有问题。

奇怪的是,如果采用系统范围的锁(如 GDI 锁),这将阻止其他 Windows 的绘制,但这不会发生。同一台机器上的 WinDbg 工作正常。 ProcessExplorer 更新但未收到鼠标点击,桌面更新但未收到鼠标点击。

我目前有一个内核调试器...

EDIT3 ETW 对调试最有用。事实证明,Qt 的主要事件处理循环发疯了。 PeekMessage 和 MsgWaitForMultipleObjectsEx(超时时间为 0)在紧密循环中被调用。这就是高 CPU 使用率的来源。 看起来应用程序当时正在生成/获取大量消息。但是要查看消息是什么并不容易(或者我不知道如何访问 ETW 中的函数参数)。使用调试器也无济于事,但是在 QT 的事件循环中使用断点让我相信 WM_TIMER 消息是罪魁祸首。

【问题讨论】:

  • 什么是windows版本?这只在这个版本上还是在所有版本上?
  • Windows 7 sp1 x64,由于某些组件仅在 Windows 7 上经过认证,因此未在其他版本上进行测试。该问题也不容易重现。它可能会在使用 2 小时后发生(这与狡猾的驾驶员理论一致)。
  • 您是否尝试过 WPA/ETW 以了解您的问题所在?
  • @magicandre1981 是的,请参阅更新后的问题。
  • 在 ETW 中看不到函数参数。您需要编写一个 ETW 提供程序并引发包含 QT 循环中事件有效负载数据中的函数参数的事件(因此需要您自己构建 QT),并且您还需要通过此用户模式提供程序捕获事件,就像我在这里展示的那样对于 .net 事件:stackoverflow.com/a/30289933/1466046

标签: windows debugging windbg


【解决方案1】:

鉴于在此期间桌面也会出现异常行为,听起来您的应用不一定是异常行为,而只是加剧了其他地方的错误(例如,在设备驱动程序中或某些已将自身注入其他进程的糟糕的反恶意软件代码中)。来自您的应用的堆栈跟踪可能会也可能不会非常有启发性。

如果问题很容易重现,我会在应用程序的“中间”某处设置断点,然后查看问题是在此之前还是之后发生。然后移动断点,直到找到应用程序在事情变得疯狂之前执行的最后一条指令。弄清楚你的应用做了什么触发了这种行为可能会为正在发生的事情提供线索。

另一种选择是尝试使用一些系统范围的调试工具。首先,我会在事件查看器中查看是否有可疑错误或警告事件发布在机器失控的那一刻附近。然后我会尝试使用像 Sysinternal 的 Process Monitor 或 Process Explorer 这样的工具来更好地了解正在发生的事情。您也可以尝试 ETW 来捕获系统范围内发生的事情的跟踪,以便事后研究。 (ETW 可能很难使用,因此请查看 Bruce Dawson 的 UIforETW。)

【讨论】:

  • 感谢您提醒我 ETW。这将比内核调试器更容易管理:)(没有火线适配器等......)
  • 另外,如果我们忘记了这个特定的问题......我很想知道什么样的系统范围的锁(或类似的东西)会阻止调试器创建的远程线程运行?有什么想法吗?
  • @Jaka - 这可能与 win32k.sys 子系统中的一些错误有关。比如说在没有禁用 APC 的情况下获取一些系统范围的资源,并且获取该资源的线程暂停。结果,当尝试获取此资源时,所有 gui 线程都可能挂起。很多年前我在 xp 上看到过这样的 - 如果暂停 gui 线程,当它处于焦点时接收进程
【解决方案2】:

使用 ETW 查找原因。安装 Windows Performance Toolkit(Win10 v1511 SDK 的一部分:https://go.microsoft.com/fwlink/p/?LinkID=698771,这是在 Win7 中工作的最后一个版本),运行 WPRUI.exe,选择 CPU Usage 并单击 Start

捕获挂起后,单击Save。等到WPRUI完成后,打开WPA中的ETL,setup and load debug symbols in WPA

拖放CPU Usage (Precise) 图表以分析窗格并为您的进程查找WAIT (µs) max 以查看long hang and expand the stack to see where it happens.

【讨论】:

    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2020-08-26
    • 2014-10-09
    • 2012-11-26
    • 2019-12-27
    相关资源
    最近更新 更多