【问题标题】:How to troubleshoot .NET 2.0 Error Reporting messages in the event log?如何对事件日志中的 .NET 2.0 错误报告消息进行故障排除?
【发布时间】:2010-10-23 07:24:24
【问题描述】:

我正在开发一个名为EVEMon 的开源产品,该产品是用 C# 编写的,针对 .NET 2.0 平台,我有一个用户正在遭受我们无法解决的奇怪的 .NET 崩溃。

事件类型:错误 事件源:.NET 运行时 2.0 错误报告 事件类别:无 事件编号:5000 日期:2009 年 4 月 29 日 时间:晚上 10:58:10 用户:不适用 电脑:删除了这个 描述: 事件类型 clr20r3、P1 evemon.exe、P2 1.2.7.1301、P3 49ea37c8、P4 system.windows.forms,P5 2.0.0.0,P6 4889dee7,P7 6cd3,P8 18,P9 system.argumentexception,P10 无。 数据: //以上描述的十六进制表示

应用程序本身崩溃但没有显示错误(尽管有错误处理 UI),上述消息是从 Windows 事件日志中复制出来的。最终用户已重新安装 .NET 并更新到最新版本。 .PDB 文件随程序的每个发布版本一起分发,以帮助调试和测试,有问题的用户拥有正确版本的 EVEMon 的完整 PDB 文件。

是否有专门的、经过验证的技术来分析和诊断这种类型的崩溃?如果是,有哪些工具和技术可用于帮助调试?

特别感谢

我要特别感谢 Steffen Opel 并强调 his answer 虽然没有直接回答我提出的问题,但解决了我的代码库中的一个更大的问题,即全局错误处理缺少一个重要组件。

【问题讨论】:

    标签: c# .net crash event-log crash-reports


    【解决方案1】:

    这就是我为最终用户解决崩溃问题的方法。

    1. http://www.microsoft.com/whdc/devtools/debugging/default.mspx下载并安装适用于 Windows 的调试工具

    2. 安装工具后(默认情况下,它们最终会转到 C:\Program Files\)启动命令行窗口。

    3. 切换到包含 adplus 的目录(例如“C:\Program Files\Debugging Tools for Windows (x86)”)。

    4. 运行以下命令。这将启动应用程序并附加 adplus。

    adplus -crash -o C:\debug\ -FullOnFirst -sc C:\path\to\your\app.exe

    创建故障转储后

    一旦应用程序崩溃启动 WinDbg 并加载在 C:\debug 中创建的 .dmp 文件。 (文件 --> 打开故障转储)

    执行这些命令以查看堆栈跟踪并希望找到问题。

    加载 SOS 进行调试

    • .NET 4.0 之前
    .loadby sos mscorwks
    
    • .NET 4.0
    .loadby sos clr
    

    查看堆栈跟踪

    !clrstack
    

    查看更有用的堆栈跟踪

    !clrstack –p
    

    戳入一个对象..也许看看是什么导致了异常

    !do <address>
    

    例如,这是由于应用程序随机出现 IO 异常而导致的结果。 WinDbg 指出被引用的路径不正确。

    0:009> !do 017f2b7c    
    Name: System.String    
    MethodTable: 790fd8c4    
    EEClass: 790fd824    
    Size: 124(0x7c) bytes    
     (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)    
    String: \\server\path\not_here.txt
    Fields:    
          MT    Field   Offset                 Type VT     Attr    Value Name    
    79102290  4000096        4         System.Int32  1 instance       54 m_arrayLength    
    79102290  4000097        8         System.Int32  1 instance       53 m_stringLength    
    790ff328  4000098        c          System.Char  1 instance       5c m_firstChar    
    790fd8c4  4000099       10        System.String  0   shared   static Empty    
        >> Domain:Value  00161df8:790d884c <<    
    7912dd40  400009a       14        System.Char[]  0   shared   static WhitespaceChars    
        >> Domain:Value  00161df8:014113e8 <<
    

    【讨论】:

    • 感谢大家的回复,感谢大家的贡献。我接受了这个答案,因为它非常具体地回答了我的问题,为我提供了与最终用户一起需要采取的步骤。
    • 我见过的最好的 SO 答案之一。简短,中肯,非常有用。
    • +1 我迫不及待想在现场的机器上尝试一下。非常感谢。
    【解决方案2】:

    查看您的源代码(主干)表明您对 Windows 窗体应用程序的未处理异常处理似乎不完整:

    您需要同时处理非 UI 线程异常和 UI 线程异常:

    • 对于前者,您需要通过 AppDomain.CurrentDomain.UnhandledException 实现 CLR 未处理的异常处理程序,该处理程序已经到位。

    • 对于后者,您需要通过 Application.ThreadException 实现一个 Windows 窗体未处理的异常处理程序,这似乎是缺失的;这确实可以产生您正在目睹的那些问题。有关实现示例,请参阅 Application.ThreadException Event 的 MSDN 文档。

    请注意,现在您明确禁止通过 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException) 捕获未处理的 Windows 窗体异常,您需要将其更改为 UnhandledExceptionMode.CatchException 以启用路由到 Application.ThreadException 的处理程序,正如 Jehof 已经正确建议的那样。

    【讨论】:

    • 这很有趣,我需要阅读这种异常处理,看看我能做些什么来解决这个问题。
    • +1 用于查看源代码 - 到目前为止,这听起来像是最好的方法。
    【解决方案3】:

    用户使用什么操作系统(Windows XP、Windows Vista 等)?

    如果 Windows Vista 尝试禁用“问题报告和解决方案功能”(控制面板-->问题报告和解决方案-->更改设置-->高级设置-->关闭我的程序、问题报告)

    或者尝试设置

      Application.SetUnhandledExceptionMode( UnhandledExceptionMode.CatchException );
    

    这将始终将异常路由到 ThreadException 处理程序。

    【讨论】:

    • 随着时间的推移,这在 Windows 7、XP 和 Vista 上出现了多个用户。上面的错误来自我相信的 Windows XP。
    【解决方案4】:

    简而言之:应用程序中存在未处理的异常。

    如果您可以访问机器(通过远程访问等),请尝试安装 Visual Studio Express 并启动应用程序。您应该会看到一个对话框,提供了使用新的 Visual Studio 实例调试应用程序的机会。

    也可能是有一些东西阻止了 Windows 窗体正确初始化。我已经看到论坛帖子表明字体问题可能导致此问题 - 确保用户安装了您的应用程序所需的字体以及通常的默认值,例如 MS SansSerif、Arial、Tahoma、Times 等。

    如果失败了...尝试在 PC 上牺牲一只鸡。每次都能发挥魅力!

    【讨论】:

    • 有问题的应用程序使用错误处理程序生成更有用的崩溃报告,其中包含向最终用户的说明(AppDomain.CurrentDomain.UnhandledException += 等...),这是一个开源项目,所以最终用户可能不希望一些随机的开发人员登录到他的计算机 - 下次发生时值得一试。
    【解决方案5】:

    我们遇到了线程代码中的异常问题。如果您生成一个新线程并忘记在线程方法中处理异常,则应用程序只会“停止” - 没有错误消息,什么都没有,而只是事件日志中的一个条目。即便如此,UnhandledExceptionHandler 也不会被触发。

    也许是这样的原因?

    【讨论】:

    • 它可能在工作线程中,尽管这些消息总是在启动时出现。
    • +1 在这里,我以前见过这个(正要回答上面的内容!)......作为追踪问题的第一次尝试,将所有执行的代码包装在完整的 try-catch 中的工作线程,它会注销任何异常并查看记录的内容..
    【解决方案6】:

    ...如果您能够联系到那个受苦的用户,这里是一个

    想法:记录预执行阶段

    不要创建program.exe 的快捷方式,而是创建program.bat 的快捷方式,这样会

    echo "Pre-start" > stage.txt
    start program.exe
    

    Program.cs 的第一行因此将是

    File.WriteAllLines("stage.txt", "Program execution started.");
    

    AppDomain.UnhandledException的处理程序中第一行将是

    File.WriteAllLines("stage.txt", "Unhandled exception has been caught.");
    

    此外,请确保处理程序不分配内存或资源——在程序启动时预先分配它们。 Handler 只触发写入日志。

    评论

    stage.txt(由用户发送)很可能包含“Pre-start”。当在第 3 方 .dll 中引发异常时会发生这种情况——甚至在您的程序启动之前。

    在这种情况下,您将需要一个简单的检查程序,它不会引用您 program.exe 所做的程序集,但会 Assembly.Load(...) 它们。

    附言

    stage.txt 应该放在 %APPDATA% 下的某个位置,而不是在 Program Files 中。

    我找到了an interesting case on Server 2003another nice discussion

    【讨论】:

      【解决方案7】:

      您应该通过将特定版本的.pdb 文件发送给用户(放在.exe 旁边)并让他们重现崩溃来获得更详细的堆栈跟踪。

      【讨论】:

      • PDB 文件与应用程序一起分发,我会检查以确保它们没有被删除。
      • 我已经与用户核实过,他确实拥有所有程序集的 .PDB 文件。
      【解决方案8】:

      你应该在代码中处理AppDomain.UnhandledException

      有人问过similar question。也可以查看相关的。

      【讨论】:

      • 我们这样做:AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
      猜你喜欢
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多