诊断生产.NET桌面程序中的应用程序挂起

诊断生产.NET桌面程序中的应用程序挂起,.net,freeze,production,diagnostics,.net,Freeze,Production,Diagnostics,我有麻烦了。我正在开发的应用程序的一个用户偶尔但经常遇到应用程序挂起的问题 发生这种情况时,我们会在机器的事件日志中找到一个源为“应用程序挂起”的条目,其中包含信息性消息“挂起应用程序[my app],版本[right version],挂起模块hungapp,版本0.0.0.0,挂起地址0x00000000。” 我正在记录我的应用程序抛出的所有未处理的异常,发生这种情况时,我的日志文件中没有任何条目 我目前的工作假设是,这种挂起是在应用程序调用不安全的遗留API期间发生的。这不会让我吃惊;我已

我有麻烦了。我正在开发的应用程序的一个用户偶尔但经常遇到应用程序挂起的问题

发生这种情况时,我们会在机器的事件日志中找到一个源为“应用程序挂起”的条目,其中包含信息性消息“挂起应用程序[my app],版本[right version],挂起模块hungapp,版本0.0.0.0,挂起地址0x00000000。”

我正在记录我的应用程序抛出的所有未处理的异常,发生这种情况时,我的日志文件中没有任何条目

我目前的工作假设是,这种挂起是在应用程序调用不安全的遗留API期间发生的。这不会让我吃惊;我已经使用这个API很多年了,虽然我以前没有见过它挂起,但它的代码真的很糟糕。此外,用户报告程序似乎在随机时间挂起。我认为这不是真的。并不是说我不相信她,而是说与遗留API对话的代码运行在由BackgroundWorker调用的方法中。如果后台线程使应用程序挂起,在用户看来,这很可能是随机发生的

所以,我有两个问题,一个具体的,一个一般的

具体的问题是:我认为如果在非UI线程上运行的方法挂起,它只会杀死线程。它真的会杀死整个应用程序吗

一般性问题:

我已经记录了所有未处理的异常。我的程序已经设置为使用跟踪(尽管我需要添加检测代码来跟踪可疑方法中的活动)。我还有其他事情要做吗?是否有诊断工具允许在.NET应用程序挂起时进行某种类型的崩溃后分析?在.NET framework中是否有机制可以调用以捕获更多(和更可用)的数据

EDIT:仔细检查我的代码,我记得BackgroundWorker的所有用法都是通过我实现的一个实用程序类实现的,该实用程序类包装了异常处理程序中调用的方法。此处理程序记录异常,然后将其作为实用程序对象的属性返回。UI线程中的完成事件处理程序重新抛出异常(不太理想,因为我丢失了调用堆栈,但它已经被记录),导致UI的主异常处理程序向消息框报告异常,然后终止应用程序

因为这些都没有发生,我很有信心在后台线程中不会抛出异常。无论如何,没有.NET例外

进一步跟进:

幸运的是,我现在已经从用户那里获得了足够的数据,以确保挂起不会发生在遗留API中。这意味着这显然是我做错了什么,这意味着我可以修复它,所以,赢了。这也意味着我可以通过跟踪来隔离问题,这是另一个胜利。我对这个问题的答案感到非常高兴;我更高兴的是,我可能不需要他们来解决这个问题

另外:PostSharp非常出色。如果您需要向现有应用程序添加插装代码,您几乎肯定应该使用它。

1)进入.net framework代码(在我的工作中从KB开始):

如果您已经安装了VS2008 SP1,那么只需转到工具->选项->调试

  • 取消选中“仅启用我的代码”
  • 选中“启用.NET Framework源代码步进”
  • 选中“启用源服务器支持”
  • 在调试->符号下,添加
  • 现在,当调试调用堆栈中灰色框架代码的东西时,只需右键单击调用行并选择LoadSymbols


    想法2)设置远程调试在回答您的特定问题时,当后台/工作线程阻塞或挂起时,对应用程序其余部分的影响将在很大程度上取决于应用程序中线程之间发生的同步。没有特定的原因说明为什么它必须挂起整个应用程序,但它是完全相关的很可能会

    一种可能的诊断方法是在进程挂起时生成进程转储(假设有人注意到它发生的时间)。这可以使用dbghelp.dll中的来完成。编写一个简单的工具来转储进程(基于其pid)是相当简单的,可以提供给遇到问题的客户。由于这是一个托管应用程序,因此最好使用完全内存转储(MiniDumpWithFullMemory),但正常转储仍应包含一些有用的信息。完成转储后,您可以使用windbg或您选择的事后调试程序查看可能发生的情况


    如果您这样做,这是托管转储调试的良好起点。

    我建议您在您认为是问题根源的调用周围添加更详细的日志记录


    如果你在Vista上,你可以使用新的Vista API在你的应用程序崩溃时让Windows调用你的代码。当你看到Office/IE等MS产品说他们正在“尝试恢复你的数据”时,就会发生这种情况。

    如果你控制的线程上有一个未经处理的执行选项,你就无法“处理”“这是线死后的事。您可能需要研究如何使用。这提供了一层保护,防止在其他线程上抛出异常,因为当您调用EndInvoke()时,会捕获并提出异常


    至于您还可以做些什么,我将给出第二个答案。

    如果可能,将后台工作线程替换为一个线程,看看它是否捕获了可疑的异常。如果没有,那么抛出的异常不是CLR异常,您可能无法从“纯”.NET代码[Seh从C++中工作] [

    处理]。
    编辑:好吧,不是这样。也许或者可能有帮助。祝你好运

    Robert,如果所有这些解决方案都失败了