我们基于表单的应用程序有一组屏幕。可以通过单击下图中突出显示的选项卡来导航屏幕。其中一个屏幕 ARAMS 屏幕(活动屏幕)是 WPF 屏幕。其他是正常形式。如果用户频繁单击不同的选项卡,然后单击 WPF 屏幕选项卡,则整个系统将挂起。问题发生后,用户必须重新启动机器。由于整个系统被挂起,我们无法调试问题。我们在调试时没有遇到问题。
应该采取什么方法来调试问题?
我们在 Win 7 机器中遇到问题
只需在进入挂起状态后使用调试器(Visual Studio 调试器或 WinDBG)“附加到进程”......然后你就可以“闯入”你的进程。
然后查看所有线程的堆栈,看看它们在做什么……你可能会发现某个特定线程正在做的事情导致死锁。
如果您使用带有 SOSEX 插件的 WinDBG,您甚至可以使用 !dlk 命令……它有时可以自动发现任何死锁。
您可以使用许多其他调试器命令来检查正在发生的事情,例如查看垃圾收集器、终结队列(例如,可能阻塞了终结器线程)等。
现在我知道你说整个系统挂起,所以这可能很棘手/不可能......你可以尝试的一件事是降低进程的进程优先级和/或在它挂起之前设置处理器亲和力状态...这应该让您有更好的机会在同一台机器上加载调试器,因为理论上您可以阻止进程过多地垄断 CPU。
转到任务管理器右键单击该进程并执行Set Priority Low或Set Affinity。
现在可能的情况是,更改优先级实际上会产生副作用,因为您的应用程序不再挂起或行为不同......但如果发生这种情况,至少这已经为您提供了有关问题的线索。
如果它仍然挂起(但没有那么多)并且您能够运行您的调试器......那么嘿,您现在可以附加到您的进程并中断它。
如果上述方法不起作用,那么是时候在崩溃的机器上安装 WinDBG,设置 Windows 以启动内核调试模式,然后从另一台机器(通过 USB、Firewire 等连接)使用 WinDBG 客户端与您的挂机后端调试引擎,这将让您闯入系统并分析机器状态。
另一种技术是通过崩溃转储捕获进程状态(您可以通过在任务管理器中右键单击进程名称并说创建转储来创建它,或者使用其他工具为您执行此操作。)。然后,您可以将 .dmp 文件加载到 Visual Studio(使用 File Open)或 WinDBG(使用 Open Crash Dump)中。然后,您可以查看该过程的某些状态。
这可以通过各种工具(例如 ADPlus)自动完成,以便在您的应用程序无响应时自动为您完成故障转储....如果您幸运的话,即使您的系统处于挂起系统中,它也可以以自动方式工作....或者它可能不会。
请注意,如果可能,最好进行实时调试而不是故障转储,因为您可以访问更多信息/状态。
可以使用 CLR 运行时运行 .NET 应用程序,执行额外检查以验证您是否以正确的方式执行操作。这些检查称为托管调试助手。当 MDA 发现问题时,它会在您的程序中引发异常。
它们可以通过使用“myapplication.mda.config”中的一些配置开关或通过“调试”菜单中的“异常”对话框来打开(树中有一个专门用于它们的分支)。需要注意的是,不要只打开所有这些,因为其中一些非常具有攻击性,可能会导致红鲱鱼……您需要真正阅读每个 MDA 并了解检查正在做什么。