如何对事件日志中的 .NET 2.0 错误报告消息进行故障排除?
-
03-07-2019 - |
题
我正在开发一个名为的开源产品 伊芙蒙 我有一个用户用 C# 编写,针对 .NET 2.0 平台,他遇到了奇怪的 .NET 崩溃问题,而我们一直无法解决该问题。
Event Type: Error Event Source: .NET Runtime 2.0 Error Reporting Event Category: None Event ID: 5000 Date: 4/29/2009 Time: 10:58:10 PM User: N/A Computer: removed this Description: EventType 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 NIL. Data: //hex representation of the above Description
应用程序本身崩溃,但没有显示错误(尽管有错误处理 UI),上述消息已从 Windows 事件日志中复制出来。最终用户已重新安装.NET并更新到最新版本。.PDB 文件随程序的每个发行版本一起分发,以帮助调试和测试,有问题的用户拥有正确版本 EVEMon 的完整 PDB 文件。
是否有一种特定的、经过尝试和测试的技术来分析和诊断此类崩溃?如果是的话,有哪些工具和技术可以帮助调试?
特别感谢
我要特别感谢斯蒂芬·欧宝并强调 他的回答 虽然没有直接回答我提出的问题,但解决了我的代码库的更大问题,即全局错误处理缺少一个重要组件。
解决方案
这就是我为最终用户解决崩溃问题的方法。
下载并安装 Windows 调试工具: http://www.microsoft.com/whdc/devtools/debugging/default.mspx
安装工具后(默认情况下它们最终会转到 C:\Program Files\),启动命令行窗口。
更改为包含 adplus 的目录(例如“C:\Program Files\Debugging Tools for Windows (x86)”)。
运行以下命令。这将启动应用程序并附加 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 <<
其他提示
查看源代码(主干)表明,对于 Windows 窗体应用程序,未处理的异常处理似乎不完整:
你需要处理 两个都 非UI线程异常和UI线程异常:
对于前者,您需要通过以下方式实现 CLR 未处理的异常处理程序
AppDomain.CurrentDomain.UnhandledException
, ,这已经就位了。对于后者,您需要通过以下方式实现 Windows 窗体未处理的异常处理程序
Application.ThreadException
, ,似乎缺失了;这确实可能会产生您所目睹的那些问题。有关实现示例,请参阅 MSDN 文档 Application.ThreadException 事件.
请注意,现在您可以通过以下方式显式禁止捕获未处理的 Windows 窗体异常: Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)
, ,你需要将其更改为 UnhandledExceptionMode.CatchException
启用路由到您的处理程序 Application.ThreadException
, ,正如 Jehof 已经正确建议的那样。
用户使用哪种操作系统(Windows XP,Windows Vista等)?
如果Windows Vista尝试禁用“问题报告和解决方案功能”, (控制面板 - &gt;问题报告和解决方案 - &gt;更改设置 - &gt;高级设置 - &gt;关闭我的程序,问题报告)
或尝试设置
Application.SetUnhandledExceptionMode( UnhandledExceptionMode.CatchException );
这将始终将异常路由到ThreadException处理程序。
简而言之:应用程序中存在未处理的异常。
如果您有权访问本机(通过远程访问等),请尝试安装Visual Studio Express并启动该应用程序。您应该看到一个对话框,提供了使用Visual Studio的新实例调试应用程序的机会。
也可能存在阻止Windows窗体正确初始化的内容。我已经看到论坛帖子提示字体问题可能导致这种情况 - 确保用户安装了您的应用程序所需的字体加上常见的默认值,如MS SansSerif,Arial,Tahoma,Times等。
失败了...尝试在PC上牺牲一只鸡。每次都有魅力!
我们遇到过Thread-Code中的例外问题。如果你生成一个新线程而忘记在线程方法中处理异常,那么应用程序只是“停止”了。 - 没有错误消息,没有任何内容,只有事件日志中的条目。甚至不会触发 UnhandledExceptionHandler
。
也许这样的事情是原因?
...如果您能够联系该受苦用户,请参阅
想法:记录预执行阶段
不要使用 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.");
此外,请确保处理程序不分配内存或资源&#8212;在程序开始时预先分配它们。处理程序仅触发写入日志。
评论
stage.txt
(由用户发送)很可能包含“预启动”。当第三方抛出异常时会发生这种情况.dll&#8212;甚至在你的程序开始之前。
在这种情况下,你需要一个简单的检查程序,它不会引用你 program.exe
所做的程序集,而是 Assembly.Load(...)
他们。
P.S。
stage.txt
应放在%APPDATA%下,而不是放在程序文件中。
您应该通过将用于该特定版本的 .pdb
文件发送给用户(放在 .exe
旁边)并拥有更详细的堆栈跟踪他们重现了崩溃。
您应该在代码中处理 AppDomain.UnhandledException
。
类似的问题问道。另见相关内容。