ブルースクリーン(BSOD) 発生時のエラーコードのことをBugCheckCodeとよび、C:\Windows\MEMORY.DMP
に出力されたダンプファイルをWinDbgで解析したり、イベントビューアーでBugCheckCodeを確認するのですが、仕事で既存のアプリにBugCheckCodeを解析・取得する機能を追加することになり、今回C#のEventLogクラスを使ってBugCheckCodeを取得しました。
※.Net Framework 4.7 を採用しています。
ソースコードサンプル
System.Diagnostics.EventLog[] logs =
System.Diagnostics.EventLog.GetEventLogs();
foreach (System.Diagnostics.EventLog log in logs)
{
// BugCheckの情報はSystemにあるので、それ以外の場合はcontinue
if (log.Log != "System")
{
continue;
}
//ログエントリを取得してsourceがBugCheckかチェックする
foreach (System.Diagnostics.EventLogEntry entry in log.Entries)
{
if (entry.Source == "BugCheck")
{
Console.WriteLine(entry.TimeGenerated.ToString() + " " + entry.EventID);
// entry.ReplacementStringsにEventDataの値が入っている
// 文字列にBugCheckCodeと4つのparmsが入っているので正規表現で分解する
var results = Regex.Matches(entry.ReplacementStrings[0], "0x[0-9a-fA-F]+");
foreach(var result in results)
{
Console.Write(result);
Console.Write(" ");
}
Console.WriteLine();
}
}
}
出力結果
2022/07/18 22:22:56 1001
0x0000007b 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000
簡単な解説
System.Diagnostics.EventLog[] logs =
System.Diagnostics.EventLog.GetEventLogs();
foreach (System.Diagnostics.EventLog log in logs)
{
// BugCheckの情報はSystemにあるので、それ以外の場合はcontinue
if (log.Log != "System")
{
continue;
}
まず、EventLog.GetEventLogs()でEventLogの配列を取得して、foreachの中でEventLog.Logの値を確認します。
EventLog.Logには上の図でいうと左ペインにある、Application
、Security
、System
などが該当します。ちなみにイベントビューアーはeventlog.logDisplayNameというローカライズされた文字(システム、セキュリティ等)を表示してます。
//ログエントリを取得してsourceがBugCheckかチェックする
foreach (System.Diagnostics.EventLogEntry entry in log.Entries)
{
if (entry.Source == "BugCheck")
{
Console.WriteLine(entry.TimeGenerated.ToString() + " " + entry.EventID);
// entry.ReplacementStringsにEventDataの値が入っている
// 文字列にBugCheckCodeと4つのparmsが入っているので正規表現で分解する
var results = Regex.Matches(entry.ReplacementStrings[0], "0x[0-9a-fA-F]+");
foreach(var result in results)
{
Console.Write(result);
Console.Write(" ");
}
Console.WriteLine();
}
あとはEventLog.Entriesでログの内容を確認して、EventLogEntry.SourceがBugCheck
か判定するだけです。
BugCheckCodeと4つのパラメータはentry.ReplacementStrings
の0番目に入っているので、今回は正規表現で後から取り出しやすいようにresults変数に代入しています。