我正在处理一个有点不可靠的(Qt / windows)应用程序,部分是由第三方为我们编写的(只是试图将责任转移到那里)。他们的最新版本更稳定。有点。我们收到的崩溃报告越来越少,但是我们收到很多关于崩溃的报告并且永远不会回来。情况多种多样,我们收集到的信息很少,我们无法重现这些问题。
理想情况下,我想创建某种监视程序,通知应用程序已锁定,并提供向我们发送崩溃报告。好主意,但有问题:
看门狗如何知道进程已挂起?据推测,我们会对应用程序进行检测,以便定期对看门狗说“一切正常”,但是我们在哪里放置它以保证频繁发生,但不太可能出现在应用程序结束时的代码路径上锁定。
看门狗在崩溃发生时应该报告什么信息? Windows有一个不错的调试api,所以我相信所有有趣的数据都是可访问的,但我不确定什么对追踪问题有用。
答案 0 :(得分:5)
你想要一个minidump的组合(如果你不想添加你自己的迷你转储生成代码,使用DrWatson创建这些)和userdump在挂起时触发minidump创建。
关于自动检测挂起的事情是,当某些事情挂起以及当它只是缓慢或被IO等待阻止时很难确定。我个人更喜欢允许用户在认为应用程序挂起时故意将其崩溃。除了更容易(我的应用程序不经常挂起,如果有的话:)),它也有助于他们“成为解决方案的一部分”。他们喜欢这样。
首先,查看关于故障转移和符号的经典bugslayer article,其中还提供了一些有关这些事情发生情况的优秀信息。
第二,get userdump允许你创建转储,instructions设置它来生成转储
当您拥有转储时,在WinDBG中打开它,您将能够检查整个程序状态 - 包括线程和调用堆栈,寄存器,内存和函数参数。我想你会特别感兴趣的是在Windbg中使用“~*kp”命令获取每个线程的callstack,并使用“!locks”命令来显示所有锁定对象。我想你会发现挂起将是由于同步对象的死锁,这很难跟踪,因为所有线程都倾向于等待WaitForSingleObject调用,但是进一步查看调用堆栈以查看应用程序线程(而不是比'框架'线程,如背景通知和网络例程)。一旦你缩小了它们,就可以看到正在进行的调用,可能会向应用程序添加一些日志记录工具,以便在下次失败时为您提供更多信息。
祝你好运。聚苯乙烯。快速谷歌提醒我:Debugging deadlocks。 (CDB是windbg的命令行)
答案 1 :(得分:2)
您可以使用Microsoft的Windows调试工具中的ADPlus来识别挂起。当进程挂起或崩溃时,它将附加到您的进程并创建转储(迷你或完整)。
WinDbg是可移植的,不必安装(但您必须配置符号)。您可以创建一个特殊的安装,它将使用批处理启动您的应用程序,它也将在您的应用程序启动后运行ADPlus(ADPlus是一个命令行工具,因此您应该能够找到一种方法以某种方式合并它。)
顺便说一句,如果你确实找到了一种在内部识别挂起并且能够使进程崩溃的方法,你可以注册Windows Error Reporting,以便将崩溃转储发送给你(如果用户允许)
答案 2 :(得分:1)
我认为一个单独的应用程序来进行监视可能会产生比它解决的问题更多的问题。我建议你首先创建处理程序以在应用程序崩溃时生成小型转储,然后将一个监视程序线程添加到应用程序,如果应用程序脱离轨道,则会发生故障。监视程序线程(与另一个应用程序相比)的优势在于监视程序应该更容易确定应用程序已经脱轨。
一旦你拥有了MiniDumps,你可以四处寻找应用程序死亡时的状态。这应该给你足够的线索来找出问题,或者至少在下一步看看。
CodeProject上有一些关于MiniDumps的内容,这可能是一个有用的例子。 MSDN也有更多关于它们的信息。
答案 3 :(得分:1)
不要打扰看门狗。订阅Microsoft的Windows错误重新保护(winqual.microsoft.com)。他们会为你收集堆栈跟踪。事实上,他们很可能今天已经这样做了;在你注册之前,他们不会分享它们。