世界を動かす技術を、日本語で。

2.5年間の実稼働後に確認された「Doom」のクラッシュが実機で発生

概要

  • DOOMエンジン の変数オーバーフロー検証実験の報告
  • 2年半 連続稼働後のクラッシュ観測
  • 実験環境や方法の詳細説明
  • 変数オーバーフローが 現実に発生 した証明
  • 結果から得られる教訓と考察

DOOMエンジン変数オーバーフロー長期実験

  • 2年半前、DOOMエンジンの挙動に興味を持ち、長期実験を開始

  • デモ再生中にカウントされる 変数 が、次のデモ開始後もインクリメントされ続ける設計

  • この変数は 前回値 と比較されており、通常運用ではオーバーフローの心配は少ない設計

  • しかし、理論上は オーバーフロー が発生し、ゲームがクラッシュする可能性を計算

  • 当時の計算では 約2年半 でオーバーフロー到達と予測

  • 実験環境として、小型PDAにDOOMをインストール

  • 電源はDIYの 18650バッテリーUPS を使用し、ルーターのUSBポートから 5V給電

  • システムを常時稼働させ、長期間放置運用

  • 本日、PDAに ポップアップ が表示され、ゲームがクラッシュしたことを確認

  • クラッシュ発生時刻は、 2年半経過直後 であり、理論値とほぼ一致

  • これにより、DOOMエンジンの該当変数が 実際にオーバーフロー し、ハードクラッシュを引き起こすことを実証

  • クラッシュ時の写真(IMG_20250916_224553.jpg)が証拠として残存

実験から得られる教訓と考察

  • 理論的なバグ も、長期運用や特殊状況下では現実化する可能性
  • 変数管理や オーバーフロー対策 の重要性を再認識
  • ハードウェアや電源供給の信頼性も、長期実験には不可欠
  • ドキュメント化の重要性 :計算や設定を記録しておくことで、後の検証や再現が容易
  • ソフトウェア設計時、 極端なケース も想定して堅牢性を高める必要性

Hackerたちの意見

2038年は楽しそうだね。

y2kの時よりもずっと近い感じがするね。

2036年のNTPについてはみんな無視してるね。そこからが本番だよ。

それを直すのが私の引退計画だよ。

約1年前にCrash Bandicootのタイマーシステムを調べてたんだけど、Crash 3には常に増加するint32があるんだ。死なない限りリセットされないから、2.26年放置するとオーバーフローしちゃう。オーバーフローすると「マイナス」時間になって、ゲームが面白い感じで壊れちゃうよ。これについて動画も作ったんだ: https://youtu.be/f7ZzoyVLu58

ファイナルファンタジー9には、プレイ時間が12時間未満で後半エリアに到達しないと手に入らない武器があるんだ。PAL版だと10時間で取得できるっていう抜け穴もあるけど。あるいは、ゲームを2年間そのまま放置してタイマーがリセットされるのを待つこともできるよ。のんびりやるのが勝ちだね。 https://finalfantasy.fandom.com/wiki/Excalibur_II_(Final_Fan...

まさか「クラッシュ」って言葉を一回も使わずに動画を作ったの?(あのフリーズはクラッシュって呼んでもいいくらいだし…)

そういうゲームは多かったと思う。SotNは確実にグローバルタイマーがあるし、32ビットのネイティブシステムだと納得できるよね。ゲームの寿命が数ヶ月から数年だった時代だし、誰も2.27年もシステムを動かしっぱなしにはしないから、テストする意味があったのかな?当時、分解されたり逆アセンブルされたりするゲームを作っているなんて誰が思ってたんだろう。自分たちが書くプログラムについてもそんなこと考えたりする?

いい動画だった、登録したよ!

まじでプレイできない状態だね、誰か直してほしい。Doomは本当にいいゲームで、数年ごとに戻ってくるんだ。2016年のリブートも結構楽しいけど、その後の2作はあんまりだったな。

同じく。あの残虐なMOD、マジで好き。

面白い事実:Doomは今やMicrosoftの所有物になったんだ。Quake、StarCraft、WarCraft、Overwatch、InfocomやSierraのアドベンチャーゲーム、そしてもちろんHaloも。MicrosoftはPCゲームのほとんどを持ってるってわけ。彼らが1996年頃からずっと望んでたことだね。

2016年は、俺がプレイした中で最高のシングルプレイヤーFPSの一つだ(Titan Fall 2もね)。

同じく。後の作品のホームハブを持つメトロイドヴァニアデザインには、同じ感覚がなかったな。走って、敵を倒して、秘密を見つけて、終わって、次のレベルに行くべきなんだよ。

これは、FPSゲームでクラシックなDOOMスタイルのプレイを好む人たち向けだよね。 https://www.reddit.com/r/boomershooters/

Doom Eternal(DOOM 2016の次の作品)以降、ゲームプレイが「相互接続されたアリーナ」スタイルにかなりシフトして、戦闘メカニクスも洗練されてきた印象がある。多くのゲームがこのデザインを採用し始めていて、例えばShadow Warrior 3とかね。このトレンドはあまり好きじゃないな。兄弟コメントでも指摘されてたけど、ブーマーシューターは一般的に古いスタイルのDOOMゲームプレイに近いけど、一部は新しいデザインを取り入れているよね。

サイトが死ぬほど使ったから、archive.orgのリンクをどうぞ: https://web.archive.org/web/20250916234009/https://lenowo.or... 残念ながら、archive.orgはサイトのフォーマットを全部キャプチャできなかったみたいだけど、テキストはちゃんとあるよ。

バグが何か分かっててよかったね。2.5年後に…「あ、デバッグログを有効にするの忘れてた」

注目すべきは、DOOMはWindows CEの前にクラッシュしたってこと。

うん、素晴らしい成果だね!

これはPDAポート特有の問題なのか、それともコアのDOOMコードの問題なのかな?@ID_AA_Carmack これを修正するパッチを書く予定はあるの?

これは、私が知っているテスターたちがやっているテストを超えてるレベルだね。昨日、私が働いているシステムで30秒のタイムアウト後にエラーハンドリングを確認するために待たされたのが5回くらいあって、ちょっとイライラしたよ。

そのハードウェアはオーバーフローをトラップするのかな?DOOMのエンジンがどう動いているかについての記事を読んだとき、デモを追跡するための変数が次のデモが始まった後も増え続けているのに気づいたんだ。この変数は、前の値を保存している別の変数と比較されてた。クラッシュするようなものには思えないけど、実際のクラッシュは何だったんだろう?

C言語では符号付きオーバーフローは未定義動作だから、何が起こるかわからないよね。でも、このクラッシュはプラットフォームやコンパイラ間で決定的っぽいから、それとは関係ないかも。TFAによると、変数が前の値と比較されているみたいで、その比較は「新しい値 < 古い値」が起こらないことを前提にしているんだろうね。もしそれが起こると、例えばスタックの破損につながる可能性がある。結局、C言語は例えば、値を返すべき関数で戻り値がない実行パスがあったら、平気で未定義動作に突入しちゃうからね。

早く!ジョン・カーマックをすぐに呼ばないと!