C# 如何对事件日志中的 .NET 2.0 错误报告消息进行故障排除?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/814560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:13:57  来源:igfitidea点击:

How to troubleshoot .NET 2.0 Error Reporting messages in the event log?

c#.netcrashevent-logcrash-reports

提问by Richard Slater

I work on an open source product called EVEMonwritten in C# targeting the .NET 2.0 platform, I have one user who is suffering from a strange .NET crash that we have been unable to resolve.

我正在开发一个名为EVEMon 的开源产品,该产品是用 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

The application itself crashes with out displaying an error (despite having a error handling UI), the above messages was copied out of the Windows Event log. The end user has re-installed .NET and updated to the latest versions. The .PDB files are distributed with every release version of the program to aid in debugging and testing, the user with the problem in question has the full complement of PDB files for the correct version of EVEMon.

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

Is there a specific, tried and tested technique to analyse and diagnose this type of crash? and if so what tools and technologies are available to aid in debugging?

是否有一种特定的、久经考验的技术来分析和诊断这种类型的崩溃?如果是这样,有哪些工具和技术可用于帮助调试?

Special Thanks

特别感谢

I would like to give special thanks to Steffen Opel and highlight that his answerwhilst not directly answering the question I was asking, addressed the bigger issue with my code base that the global error handling was missing an important component.

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

采纳答案by Michael Baker

This is how I would tackle the problem for a end user with a crash.

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

  1. Download and install Debugging Tools for Windows at http://www.microsoft.com/whdc/devtools/debugging/default.mspx

  2. Once the tools are installed (they end up going to C:\Program Files\ by default) start a command line window.

  3. Change to the directory which contains adplus (e.g "C:\Program Files\Debugging Tools for Windows (x86)").

  4. Run the follwing command. This will start the application and attach adplus.

  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

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

After the crash dump is created

创建故障转储后

Once the application crashes start WinDbg and load the .dmp file that is created in C:\debug. (File --> Open Crash Dump)

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

Execute these commands to see the stack trace and hopefully find the problem.

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

To load SOS for debugging

加载 SOS 进行调试

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

To see the stack trace

查看堆栈跟踪

!clrstack

To see a more useful stack trace

查看更有用的堆栈跟踪

!clrstack –p

To poke inside an object..perhaps see what caused the exception

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

!do <address>

e.g This is the result from a application that faulted randomly with an IO exception. WinDbg pointed out the path that was being referenced which was incorrect.

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

0:009> !do 017f2b7c    
Name: System.String    
MethodTable: 790fd8c4    
EEClass: 790fd824    
Size: 124(0x7c) bytes    
 (C:\WINDOWS\assembly\GAC_32\mscorlib.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 <<

回答by S?ren Kuklau

You should get a more detailed stack trace by sending the .pdbfile for that particular release to the user (to be put next to the .exe) and having them reproduce the crash.

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

回答by Jeremy McGee

In a nutshell: there is an unhandled exception in the application.

简而言之:应用程序中有一个未处理的异常。

If you have access to the machine (through remote access, etc.), try installing Visual Studio Express and starting the application. You should see a dialog offering the chance to debug the application with a new instance of Visual Studio.

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

It may also be that there is something preventing Windows Forms from properly initializing. I've seen forum posts that suggest that font issues can cause this -- ensure that the users have the fonts installed that your application needs plus the usual defaults such as MS SansSerif, Arial, Tahoma, Times and suchlike.

也可能是某些原因阻止了 Windows 窗体正确初始化。我看到论坛帖子表明字体问题可能导致这种情况——确保用户安装了您的应用程序需要的字体以及通常的默认值,例如 MS SansSerif、Arial、Tahoma、Times 等。

And failing that... try sacrificing a chicken over the PC. Works a charm every time!

失败了...尝试在PC上牺牲一只鸡。每次都有魅力!

回答by Thorsten Dittmar

We've had issues with Exceptions in Thread-Code. If you spawn a new Thread and forget to handle an exception in the thread method, the application just "stops" - no error message, no nothing, but only an entry in the Event Log. Not even then UnhandledExceptionHandleris triggered.

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

Maybe something like this is the cause?

也许是这样的原因?

回答by Jehof

What OS (Windows XP, Windows Vista, etc.) does the user use?

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

If Windows Vista try to disable "Problem Reports and Solutions feature" (Control Panel-->Problem Reports and Solutions-->Change Settings-->Advanced Settings-->Turn off for my programs, problem reporting)

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

Or try to set

或者尝试设置

  Application.SetUnhandledExceptionMode( UnhandledExceptionMode.CatchException );

This will always route exceptions to the ThreadException handler.

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

回答by bohdan_trotsenko

You should handle AppDomain.UnhandledExceptionin code.

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

There was a similar questionasked. See related ones too.

有人问过类似的问题。也可以看看相关的。

回答by bohdan_trotsenko

...if you are able to contact that suffering user, here is an

...如果你能联系到那个受苦的用户,这里有一个

Idea: log pre-execution stages

思路:记录预执行阶段

Instead of making a shortcut to your program.exe, make a shortcut to program.bat, which will

与其创建指向您program.exe的 的快捷方式program.bat,不如创建指向 的快捷方式,这将

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

The first line of Program.cswill therefore be

因此,第一行将Program.cs

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

In the handler of AppDomain.UnhandledExceptionfirst line will be

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

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

Also, make sure that the handler does not allocate memory or resources — pre-allocate them on programs start. Handler only trigger the writing to the log.

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

Comments

注释

It is very likely that the stage.txt(sent by the user) will contain "Pre-start". This happens when an exception is thrown in 3rd party .dll — even before your program has started.

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

In that case you will need a simple checker program, which will not reference the assemblies that you program.exedoes, but will Assembly.Load(...)them.

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

P.S.

聚苯乙烯

stage.txtshould be placed somewhere under %APPDATA%, not in Program Files.

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

I found an interesting case on Server 2003and another nice discussion.

我发现了一个关于 Server 2003 的有趣案例另一个很好的讨论

回答by Steffen Opel

Peeking into your source code (trunk) indicates that your unhandled exception handling seems to be incomplete in regard to Windows Forms applications:

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

You need to handle bothnon-UI thread exceptions and UI thread exceptions:

你需要处理两个非UI线程异常和UI线程例外:

  • For the former you need to implement a CLR unhandled exception handler via AppDomain.CurrentDomain.UnhandledException, which is in place already.

  • For the latter you need to implement a Windows Forms unhandled exception handler via Application.ThreadException, which seems to be missing; this could indeed yield exactly those problems you are witnessing. For an implementation example see MSDN documentation of Application.ThreadException Event.

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

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

Please note that right now you explicitly suppress catching unhandled Windows Forms exceptions via Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException), you'll need to change this to UnhandledExceptionMode.CatchExceptionto enable routing to your handler for Application.ThreadException, as correctly suggested by Jehof already.

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