代码之家  ›  专栏  ›  技术社区  ›  Ned

当我的应用程序锁定在客户的计算机上时的故障报告监视程序

  •  4
  • Ned  · 技术社区  · 17 年前

    我正在处理一个有点不可靠的(qt/windows)应用程序,它的一部分是由第三方为我们编写的(只是试图转移责任)。他们的最新版本更稳定。某种程度上。我们收到的车祸报告更少了,但我们收到了很多关于车祸的报告,只是挂着不回来。情况各不相同,我们收集到的信息很少,我们无法重现问题。

    所以理想情况下,我想创建某种看门狗,它会注意到应用程序已锁定,并提议将崩溃报告发送回我们。好主意,但也有问题:

    • 看门狗如何知道进程已挂起?假设我们对应用程序进行检测,以便定期对看门狗说“一切正常”,但是我们应该把它放在哪里,这样它就可以保证足够频繁地发生,但不太可能出现在应用程序锁定时的代码路径上。

    • 发生车祸时,看门狗应该报告什么信息?Windows有一个很好的调试API,所以我相信所有有趣的数据都可以访问,但是我不确定什么对跟踪问题有用。

    4 回复  |  直到 17 年前
        1
  •  5
  •   gbjbaanb    17 年前

    您需要一个小型转储(如果不想添加自己的小型转储生成代码,请使用drwatson创建这些)和userdump的组合来触发挂起上的小型转储创建。

    自动检测一个挂起的问题是,很难决定什么时候挂起某些东西,什么时候它只是缓慢或被IO阻塞等待。我个人更喜欢让用户在认为应用程序挂起时故意破坏它。除了要容易得多(如果有的话,我的应用不会经常挂起),它还可以帮助他们“成为解决方案的一部分”。他们喜欢这样。

    首先,看看经典 bugslayer article 关于崩溃转储和符号,它也有一些关于这些事情的好信息。

    第二,得到 userdump 它允许您创建转储,以及 instructions 用于将其设置为生成转储

    当您有转储文件时,在windbg中打开它,您将能够检查整个程序状态——包括线程和调用堆栈、寄存器、内存和函数的参数。我想你会特别有兴趣使用 ~*kp “windbg中的命令获取每个线程的调用堆栈,以及”!locks”命令显示所有锁定对象。我认为您会发现挂起是由于同步对象的死锁造成的,这将很难跟踪,因为所有线程都倾向于等待一个WaitForSingleObject调用,但进一步查看调用堆栈以查看应用程序线程(而不是后台通知和网络例程之类的“框架”线程)。一旦你缩小了范围,你就可以看到正在进行的调用,可能会在应用程序中添加一些日志记录工具,以便在下次失败时为你提供更多的信息。

    祝你好运。

    快速谷歌提醒我: Debugging deadlocks . (cdb是与windbg等效的命令行)

        2
  •  2
  •   Eran    17 年前

    你可以使用 ADPlus 从Microsoft的Windows调试工具中识别挂起。它将附加到您的进程,并在进程挂起或崩溃时创建一个转储(mini或full)。

    windbg是可移植的,不必安装(但是,您必须配置符号)。您可以创建一个特殊的安装,它将使用批处理启动您的应用程序,在应用程序启动后也将运行adplus(adplus是一个命令行工具,因此您应该能够找到一种方法以某种方式合并它)。

    顺便说一句,如果您确实找到了一种内部识别挂起的方法,并且能够使进程崩溃,那么您可以注册到 Windows Error Reporting 以便将崩溃转储发送给您(如果用户允许)。

        3
  •  1
  •   Michael Kohne    17 年前

    我认为一个单独的应用程序进行监视可能会产生比它解决的问题更多的问题。我建议您首先创建处理程序,在应用程序崩溃时生成小型转储,然后向应用程序添加一个看门狗线程,如果应用程序脱离轨道,它会故意崩溃。看门狗线程(与其他应用程序相比)的优势在于,看门狗应该更容易知道应用程序是否偏离了轨道。

    一旦你有了小型垃圾堆,你就可以四处看看,看看应用程序的状态。这应该给你足够的线索来找出问题所在,或者至少下一步该去哪里看看。

    在代码项目中有一些关于 MiniDumps 这可能是一个有用的例子。关于它们,msdn也有更多的信息。

        4
  •  1
  •   MSalters    17 年前

    别打扰看门狗了。订阅Microsoft的Windows错误修复(winqual.microsoft.com)。他们会为你收集StackTraces。事实上,很可能他们今天已经这样做了;在你注册之前他们不会分享他们。