1 ポイント 投稿者 GN⁺ 2025-04-24 | 1件のコメント | WhatsAppで共有
  • GTA San Andreasの20年前のバグがWindows 11 24H2で表面化
    • GTA San AndreasでSkimmer飛行機がWindows 11 24H2で消えるバグが報告された
    • SilentPatchを使っても問題は解決しない
    • Windows 11 23H2では問題は発生しない
    • Windows 11 24H2に更新したユーザーは全員このバグを経験している

バグ調査

何が間違っていたのか?

  • SilentPatchをインストールするとゲームがフリーズする問題が発生
  • CPlane::PreRenderで小さなループに閉じ込められる現象を発見
  • 飛行機のブレード速度が異常に高く設定されている
  • ブレード速度は飛行機の高度に比例して計算される

なぜ、そしてどのように?

  • Skimmerのvehicles.ide定義で必要なパラメータが欠落していた
  • Vice CityではSkimmerはボートとして定義されていた
  • San Andreasで飛行機に変更されたが、必要なパラメータが追加されなかった

真の根本原因

  • Windows 11 24H2でスタック使用方法が変更され、問題が発生した
  • LeaveCriticalSectionがスタック領域をより多く使うようになった
  • 以前はfgetsLeaveCriticalSectionがスタック領域を上書きしていなかったが、今では上書きするようになった

この問題が今になって発生した理由

  • Windows 11 24H2の変更によりスタック領域が変化した
  • ゲームが初期化されていないローカル変数を使用していたことで発生した問題
  • 他のプラットフォームではすでに修正されていた問題だった

ゲームでこの問題を解決したいなら?

  • 次回のSilentPatchホットフィックスにコード修正が含まれる予定
  • vehicles.ideファイルを手動で修正して問題を解決することも可能

最後に

  • このバグは特定のOSリリースと直接結びついている点が興味深い
  • スタックレイアウトの変更が互換性に影響し得ることを示している
  • 入力データを検証し、コンパイラ警告を無視しないことが重要だ

1件のコメント

 
GN⁺ 2025-04-24
Hacker Newsの意見
  • Raymond Chenの仕事を期待してよさそうな内容。これは非常に高い賛辞だ
  • 問題の原因をさらに深く追跡したことがうれしい
  • 個人的には、契約の一部でないものはランダムに扱うべきだと思う。たとえば、言語でマップの反復順序が保証されていないなら、言語はそれをランダムにすべきだ。そうでなければコードが不安定になる
  • コンパイル警告を無視すべきではない。このコードは元のコードで警告を発していた可能性が高い
  • ここで想定できるコンパイラの警告は何だろう? おそらく scanf の戻り値を確認せず、引数の数と一致しているか検証していないことだろう。それ以外だと、コンパイラには分からないデータファイルのエラーのように見える
  • 技術的な記事を読むのはいつも楽しい。AI時代にこうした記事がどれほどさらに珍しくなるのか気になる
  • Windowsのクリティカルセクションのロック/アンロック実装で何が変わったのか気になる
  • アクセスに問題を抱える人向けのリンクを提供
  • スタックを越えて読み書きするのはいつもあまりにも簡単だった。これは単純に失敗すべきだ
  • 緩和策は存在する。ASLR、NXページ、スタックスマッシング保護など。しかし、スタックを越えた古いデータの読み取りを完全に防ぐことはできない
  • ハードウェアがスタック領域の未使用部分を読み書きできないようにしたらどうなるか、という思考実験
  • スタックの開始アドレスA、サイズS、現在の深さDを追跡する方法の提案
    • CPUにスタックがアドレスAにサイズSで存在すると知らせる命令を追加
    • スタックにNバイトを予約するジャンプ命令を追加
    • 既存のリターン命令にスタック認識機能を追加
    • 現在の深さを超えたスタック領域への読み取りまたは書き込みを失敗させる
    • スタックが下方向に成長するアーキテクチャでは、算術は逆に適用される
  • 欠点としては、1つの呼び出し規約を固定してしまい、CPUメモリ管理機構に多くの状態が必要になる
  • スタックはいたるところに存在する。ハードウェアのスタック認識は新たな緩和策を切り開く
  • なぜこのアイデアは一般的ではないのだろう? 試されたことはあるのだろうか?
  • これらすべての発見は、Windows 11 24H2の問題ではないことを証明している。ゲームが未定義動作に依存しているのだ
  • 未定義動作は非常に厄介で、すでに間違っているのに自分が正しいと信じ込ませてしまう
  • CまたはC++プログラムが未定義動作を引き起こすと、プログラム実行では何でも起こり得る
  • 運が良ければ、プログラムは適切なエラーメッセージを表示するかクラッシュして、問題があることをすぐに知らせてくれる
  • 運が悪ければ、プログラムはデータを静かに破壊し、問題に気づく頃には原因が過去の実行履歴に埋もれている
  • 非常に運が悪ければ、プログラムは望みどおりに動作していたのに、無関係なコードやコンパイラのバージョン、OSなどを変更したとたん新しいバグが現れる
  • 開発者として、より良い方法を見つけるための提案
    • CまたはC++における未定義動作を読み、理解し、覚え、それを避けるべきだ
    • アプリケーションをデバッグモードでコンパイルし、リリースモードと比較して差異があれば深刻な問題がある
    • 実行時に未定義動作を捕捉するために -fsanitize=undefined,address のようなツールを使う
    • Java、C#、Pythonのような管理言語の使用を勧める。あるいはRustのような安全な低レベル言語を使う
  • デバッガの使用を勧める。デバッガを使わないことの問題についての話を聞いた
  • Silentに大きな愛を送る。10年以上にわたって、私の好きなゲームを改善してくれた