crash-sentinel: Windows の電源断にブラックボックスを付ける
crash-sentinel は純 PowerShell 製の Windows クラッシュモニターで、突然画面がブラックアウトして電源が落ち、再起動して戻ってくると Kernel-Power Event 41 が一件あるだけ、というケースを専門に扱う。Event 41 は「正常にシャットダウンしなかった」ことだけを伝え、その理由は教えてくれない。crash-sentinel がやるのは二つ。クラッシュ前に現場を録画すること、そしてクラッシュ後に死因を自動で特定することだ。
純 PowerShell 5.1、依存ゼロで、温度を見るためだけに監視ソフトを山ほど入れる必要はない。GPU は nvidia-smi 経由(NVIDIA ドライバーを入れていれば付いてくる)、CPU 負荷はパフォーマンスカウンター経由、CPU 温度は ACPI 熱区から読む。すべてシステムに既にあるものだ。run.bat をダブルクリックすれば動き、5 秒ごとに GPU/CPU の温度・消費電力・負荷をサンプリングし、一件ずつタイムスタンプ付きの CSV に書き込む。コンソールは色分けされていて、緑は正常、黄はやや熱め、赤は危険、危険のときは beep も鳴るので、横目で一瞥すれば状態が分かる。
肝心なのは、電源断でデータを失ってはいけないという点だ。捕まえようとしているのがまさに突然の電源断である以上、ログの書き込みは絶対にバッファリングに頼ってはならない——最後の数秒がメモリに溜まったままディスクに落ちておらず、電源断が来れば全部消えてしまい、監視した意味がなくなる。だから一件サンプリングするたびに即座にディスクへ flush する。多少 IO が増えてもそのほうがいい。
クラッシュして再起動したら CrashReport.ps1 を走らせる。まずイベントログで Event ID 41 を探して本当に予期しない電源断だったかを確認し、次に直近の監視ログをめくってクラッシュ前の数分間を取り出して性質を判定し、ざっと見る用の .txt と曲線を見る用の .html を出す。レポートはこんな感じになる:
DIAGNOSIS:
THERMAL THROTTLE CRASH: GPU hit critical temp (86C).
Sustained near-max temps caused VRM/power delivery to overload.
RECOMMENDATIONS:
- Cap frame rate to reduce sustained GPU load
- Limit GPU power target to 80-85%
- Improve laptop ventilation
自分のこのマシンは、GPU が長時間 80 度台に貼り付き消費電力は 160W まで振り切っていた。ソフトが吹っ飛んだのではなく、熱と電源供給が持ちこたえられなかったのだ。その後、電力上限を 85% まで下げてフレームレートをロックしたら、電源断は再発しなくなった。
落とし穴もある。CPU 温度は最初ほとんど動かなかった。調べてみると ACPI 熱区が読んでいるのはパッケージ温度でコアの die 温度ではなく、一部のノートは保守的な値を出す。そこで GPU の温度と消費電力を主指標にした。この二つこそが真犯人だ。閾値・サンプリング間隔・ログパスはすべて settings.json にあるので、スクリプトを書き換える必要はない。setup.bat を管理者権限で一度走らせると二つのタスクスケジューラーを登録する。一つはログイン時に自動で監視を開始するもの、もう一つは起動時にクラッシュを検出しあれば report を出すものだ。今のところ NVIDIA カードのみ対応で、診断チェーンが nvidia-smi の上に組まれている。AMD は手元にカードがないのでひとまず保留にしている。