イベントログの.NET 2.0エラー報告メッセージのトラブルシューティング方法
-
03-07-2019 - |
質問
.NET 2.0プラットフォームをターゲットにしたC#で記述された EVEMon というオープンソース製品に取り組んでいます。解決できなかった奇妙な.NETクラッシュに苦しんでいるユーザーが1人います。
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ファイルを完全に補完します。
このタイプのクラッシュを分析および診断するための、具体的かつ試行され、テストされた手法はありますか?もしそうなら、デバッグを支援するためにどのツールとテクノロジーが利用可能ですか?
特別な感謝
Steffen Opelに特に感謝し、そのことを強調したい彼の答えは、私が尋ねていた質問に直接答えていませんが、グローバルなエラー処理に重要なコンポーネントが欠けているというコードベースの大きな問題に対処しました。
解決
これは、クラッシュしたエンドユーザーの問題に取り組む方法です。
-
ツールをインストールしたら(デフォルトでは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>
e.gこれは、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スレッド例外を処理する必要があります:
-
前者については、既に設置されている
AppDomain.CurrentDomain.UnhandledException
を介してCLR未処理の例外ハンドラを実装する必要があります。 -
後者の場合、Windowsフォームの未処理の例外ハンドラを
Application.ThreadException
経由で実装する必要がありますが、これは欠落しているようです。これにより、実際に目撃している問題が正確に生じる可能性があります。実装例については、 Application.ThreadExceptionのMSDNドキュメントを参照してください。イベント。
現在、 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)
を介して未処理のWindowsフォーム例外のキャッチを明示的に抑制していることに注意してください。これを UnhandledExceptionMode.CatchException
すでにJehofが正しく示唆しているように、 Application.ThreadException
のハンドラーへのルーティングを有効にします。
ユーザーが使用しているOS(Windows XP、Windows Vistaなど)
Windows Vistaで「問題のレポートとソリューション機能」を無効にしようとした場合(コントロールパネル->問題レポートとソリューション->設定の変更->詳細設定->プログラムの無効化、問題の報告)
または設定を試みます
Application.SetUnhandledExceptionMode( UnhandledExceptionMode.CatchException );
これにより、常に例外がThreadExceptionハンドラにルーティングされます。
簡単に言うと、アプリケーションに未処理の例外があります。
マシンにアクセスできる場合(リモートアクセスなどを使用)、Visual Studio Expressをインストールしてアプリケーションを起動してみてください。 Visual Studioの新しいインスタンスでアプリケーションをデバッグする機会を提供するダイアログが表示されます。
Windowsフォームが適切に初期化されない原因がある可能性もあります。フォントの問題がこれを引き起こす可能性があることを示唆するフォーラムの投稿を見てきました-ユーザーがアプリケーションに必要なフォントと、MS SansSerif、Arial、Tahoma、Timesなどの通常のデフォルトをインストールしていることを確認してください。
これに失敗すると... PCの上で鶏を犠牲にしてみてください。毎回魅力的です!
スレッドコードの例外に問題があります。新しいThreadを生成し、threadメソッドで例外を処理するのを忘れると、アプリケーションは単に「停止」します。 -エラーメッセージも何もありません。イベントログのエントリのみです。その後も 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
は、Program Filesではなく、%APPDATA%の下のどこかに配置する必要があります。
特定のリリースの .pdb
ファイルをユーザーに送信して( .exe
の隣に配置)、さらに詳細なスタックトレースを取得する必要があります。それらはクラッシュを再現します。
コードで AppDomain.UnhandledException
を処理する必要があります。
同様の質問が尋ねられました。関連するものも参照してください。