【发布时间】: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