web-dev-qa-db-ja.com

パックマンのゲームの「レベル256のバグ」は、未処理のセグメンテーションフォールトと見なすことができますか?

私は誰かにセグメンテーション違反を説明しようとしています、そして私はパックマンのレベル256キルスクリーンについて考えていました、そしてそれは整数オーバーフローによってどのように引き起こされ、振る舞いはセグメンテーションでしばしば説明される「未知の状態」に似ていますか障害。

これは私が「未処理のセグメンテーションフォルト」と呼ぶものの良い例だと言いたいのですが、誤った情報を広める前にセカンドオピニオンを得たいと思います。

調べてみましたが、バグ自体に関するドキュメントと、Hipster WhaleとNamcoの共同作業によるものです。

では、パックマンのレベル256での動作は、未処理のセグメンテーション違反の例であると考えますか?

51
Braden Best

絶対にありません。

割り当てていないメモリアドレスへのアクセスは、常にプログラミングエラーです。そして、そこから得た情報に基づいて行動すると、未定義の動作が発生します。元のパックマンがどのプラットフォーム用に作成されたかはわかりませんが、他のフォンノイマンマシンと同じようにこの動作を示したと確信しています。

ただし、「セグメンテーションフォールト」は、より具体的な状態を表す専門用語です。これは、コンピュータこれが発生したことを自動的に検出するで発生し、未定義の動作を発生させるのではなく、プロセスを終了します。これには、高度な所有権タグ付けを備えた特定の(セグメント化された)メモリモデルが必要です。私は1980年のアーケードゲームにそれがあったとは思いません。実際、ゲームの動作はエラーがnotが検出され、未定義の動作didが発生したことを示唆しています。

113
Kilian Foth

「未定義の動作」と「セグメンテーション違反」を混同しているようです。

未処理のセグメンテーションフォルトなどはありません。セグメンテーション違反is定義によりエラー処理。

不正なメモリアクセスを検出して安全のためにプロセスを終了したOSがない場合、セグメンテーションエラーはありません。

どちらかといえば、これはUB しないが常にsegfaultをもたらす方法のかなり良い例です。

これらの用語はどちらも、アセンブリ言語でプログラムされ、メモリ保護ハードウェアやオペレーティングシステムの利点なしに実行されるアーケードゲームのバグには適していません。

"Undefined behaviour"はCおよび関連言語の用語であり、1989年にC標準委員会が作成したものです。言語仕様が定義されていない場合、コードは未定義の動作をしますそれが何をするか。 Z80アセンブリ言語にはそのようなものはありません。あらゆる可能な入力を持つすべてのオペコードの効果は明確に定義されています。 「未定義の動作」の従来の英語の意味は、適用して読むことができます-キル画面は、ゲームを書いた人によって定義されていない動作です-しかし、私はこのコンテキストでは間違った結果を与える可能性が高いため、使用しません。印象。

「セグメンテーション違反」はPOSIXの用語であり、最終的にはPDPシステムプログラミング用語から派生したものです。セグメンテーション違反は、プログラムが何にも「マッピングされていない」メモリアドレスにアクセスしようとすると発生します。ハードウェアとオペレーティングシステムがこれを検出し、プログラムが回復する機会を与える慎重に定義された方法で、誤動作しているプログラムをシャットダウンします。 。パックマンの回路基板はZ80の64kBの半分未満しか実装されていないため、パックマンゲームプログラムのバグの結果としてのようなものが発生した可能性があります。 ROM、RAM、およびペリフェラルを含むアドレス空間ですが、ソフトウェアがマップされていないメモリにアクセスしようとした場合、実際のハードウェアが何をするかを見つけることができませんでした。ただし、パックマンの「オペレーティングシステム」は1つ持っているため、「セグメンテーション違反」と表現するのは不適切です。 )はUnixの実装ではなくであり、これもまた誤った印象を与えます。

一方、レベル256のバグは、マップされていないメモリにアクセスしないため、問題はありません。

ゲームにはbugがあり、レベル256に進むと明らかになります。バグの根本的な原因は整数オーバーフロー、およびその結果がメモリ破損(または、同等に、メモリおよびタイプセーフティの違反)。これらはすべて、特定の言語またはOS環境を参照せずに定義された汎用のCS用語です。

バグの効果ではないメモリ破損バグの現代環境における効果と同様であることを確認することも正確ですセグメンテーション違反を引き起こします。 Project Zero エクスプロイト記事のいずれかを読んだ場合、Don Hodgesの パックマン殺害画面の分析 と非常によく似ています。

パックマンROMを供給したときにキル画面を忠実に再現しないエミュレータは、ゲームハードウェアを正しくエミュレートしないことに注意してください。

24
zwol

パックマンのレベル256のバグにより、プログラムreading dataが意図されたテーブルの終わりを超えていますが、まだ読み取り可能なストレージであり、プログラムが書こうとしている画面を超えているが、プログラムが書き込みを許可されている画面の領域内にあるである画面。他のメモリ領域は影響を受けません。

バグがゲームをプレイできないようにする理由は、プレーヤーが画面上にあるものを調べてプレーヤーがドットを食べているときを判別し、プレーヤーが244ドットを食べたときにレベルが完了したと判断するためです。画面の一部を上書きすることにより、バグはプレイヤーが244ドットを食べることを不可能にします。その結果、ゲームはレベルを完了したことをプレーヤーにクレジットして、画面にドットをリロードすることは決してありません。

8
supercat

前に言ったように、それはセグメンテーションフォールトではありません。問題が発生する理由を追加します。それはoverflowです。

レベル番号はバイトに格納されるため、範囲は0〜255です。レベルを完了するたびに、カウンターは増加します。レベル256では、オーバーフローのため、カウンターは実際には0です。

ただし、ゲームはレベルの下部にいくつかの果物を表示しようとします。果実の数/種類はレベルによって異なります。数式では、レベル8の完成したレベルごとに1つの果物が表示されます。カウンターによると、レベル0の8未満です。テストは真であり、255個の果物(古いレベル値)を印刷する必要があります。これは不可能であり、この不具合のある画面を表示します。

1
Romain Picot