팩맨 게임에서 "레벨 256 버그"가 처리되지 않은 segfault로 간주 될 수 있습니까?


51

나는 누군가에게 세그먼테이션 결함을 설명하려고 노력하고 있는데, 팩맨의 레벨 256 킬 스크린과 그것이 정수 오버플로에 의해 어떻게 트리거되는지, 그리고 그 행동이 세그멘테이션에서 묘사 된 "알 수없는 상태"와 얼마나 비슷한 지에 대해 생각하고 있었다. 결점.

나는 이것이 "처리되지 않은 segfault"라고 부르는 것의 좋은 예라고 말하고 싶지만, 잘못된 정보를 퍼 뜨리기 전에 두 번째 의견을 얻고 싶습니다.

나는 그것을 찾으려고 노력했지만 Hipster Whale과 Namco 사이의 충돌뿐만 아니라 버그 자체에 대한 문서 만 얻었습니다.

Pacman 256 레벨의 동작이 처리되지 않은 분할 위반의 예라고 생각하십니까?


3
다음은 버그를 수정하는 패치와 함께 버그에 대한 정확한 설명입니다. donhodges.com/how_high_can_you_get2.htm
abligh

26
불법적 인 메모리 액세스를 피하기 위해 하드웨어에서 세그먼트 오류가 발생합니다. 나는 Pacman에 대한 전문가는 아니지만, 하드웨어가 실행 된 하드웨어에는이 안전 기능이 없었습니다.
BlueRaja-대니 Pflughoeft

3
Wikipedia 에 따르면 Pacman은 Z80을 사용했습니다. Z80에는 메모리 보호 기능이 없었습니다.
로봇 고트

이 시스템은 segfault가 아닙니다. 시스템에는 어떠한 형태의 메모리 보호 기능도 없었습니다. 레벨 256에서 팩맨이 경험 하는 결함 은 단순히 게임 코드에 의해 올바르게 처리되지 않는 정수 오버플로입니다.
bwDraco

3
참고로, 이것이 버그라고 생각하지 않습니다. 버그는 컴퓨터 프로그램 또는 시스템의 고장 또는 결함으로, 잘못되거나 예기치 않은 결과가 발생하거나 의도하지 않은 방식으로 동작합니다. 그것은 한 의도적 는 아무도 그 수준에 얻을 것이라고 생각 되었기 때문에, 그런 식으로 프로그램. 실제로 소프트웨어 디자인이 열악합니다.
Keltari

답변:


113

기필코 아니다.

할당하지 않은 메모리 주소에 액세스하는 것은 항상 프로그래밍 오류입니다. 그리고 정보에서 얻은 정보에 대한 행동은 정의되지 않은 행동을 만들어냅니다. 나는 원래 팩맨이 어떤 플랫폼을 위해 쓰여 졌는지 전혀 몰랐지만 다른 폰 노이만 머신과 마찬가지로이 동작을 보여 주었다고 확신한다.

그러나 "세그먼트 결함"은 훨씬 구체적인 조건을 나타내는 기술 용어입니다. 컴퓨터 가이 문제가 발생했음을 자동으로 감지하고 정의되지 않은 동작이 발생하지 않고 프로세스가 종료 될 때 발생합니다. 이를 위해서는 정교한 소유권 태그가 지정된 특정 (분할 된) 메모리 모델이 필요합니다. 나는 1980 년 아케이드 게임이 있었고, 실제로 게임의 동작은 오류가되었다는 것을 시사한다 생각하지 않는다 하지 감지하고 정의되지 않은 동작이 않았다 발생합니다.


19
@ B1KMusic : 당신은 정말 물어 "이 코드 '버그'범위를 벗어날 메모리 액세스를 통해 정의되지 않은 동작을 호출의 예입니다"하고 대답은 "예"입니다. SIGSEGV 신호를 얻지 않고 잡기, 무시하기에 대한 합리화는 혼란스러운 문제입니다.
Monica와의 가벼움 경주

5
@ B1KMusic 모든 버퍼 오버런으로 segfault가 발생하는 것은 아닙니다. 메모리 할당 방법에 따라 다릅니다. 메모리가 정적으로 할당되고 (하나의 큰 버퍼가 다른 영역에서 수동으로 분할 됨) 마지막 수준 바로 뒤에있는 영역이 스프라이트 그래픽과 같은 용도로 사용 된 경우 segfault가 아닙니다.
ratchet freak

6
이 오래된 아케이드 시스템은 초기 버전의 DOS와 마찬가지로 하드웨어를 거의 완전히 제어 할 수있는 기본 OS를 사용했습니다. 해당 유형의 아키텍처에서 segfault에 대한 아이디어는 시작 프로세스가 아닙니다. 실행중인 프로세스 (Pac-Man)가 모든 메모리를 소유 하지 않는다고 가정하기 때문 입니다. 더 자세한 정보는 MAME 프로젝트 와 그 역사를 읽을 수 있습니다 .

20
정의되지 않은 동작은 von Neumann 머신의 속성이 아니며 프로그래밍 언어 인 C의 속성입니다. 어셈블리 언어 명령어의 동작은 항상 정의되어 있기 때문에 어셈블리 언어로 작성된 프로그램은 정의되지 않은 동작을 나타낼 수 없습니다 (결과가 때때로 지정되지 않은 경우에도).
Dietrich Epp

8
@ Snowman Pac-Man 머신에는 이러한 레이어가 없습니다. 로더가 없습니다. 게임이 제자리에서 실행 ROM에 있습니다. 메모리 관리가 없습니다. 모든 것이 정적 인 것입니다. "서비스"는 없습니다. 게임은 하드웨어에 직접 액세스하고 게임에 포함되지 않고 게임용으로 작성된 시스템에는 코드 바이트가 없습니다.
hobbs

38

"정의되지 않은 동작"과 "세그먼트 결함"을 혼동하는 것 같습니다.

처리되지 않은 segfault와 같은 것은 없습니다. 세그먼테이션 결함 정의에 따른 오류 처리입니다.

잘못된 메모리 액세스를 감지하고 안전을 위해 프로세스를 종료 한 OS가없는 경우 세그먼테이션 오류가 없습니다.

그렇다면 UB 항상 segfault를 생성 하지 않는 방법에 대한 좋은 예입니다 .


2
정확하게하기 위해 OS 프로세스를 강제 종료 (즉, 복구 불가능하게)하기로 결정할 수 있습니다 . 현대의 OS 대신하는 것을 선호 종료 붙잡고, FWIW을 처리 할 수있는, 그것을.
edmz

@black : 내가 말한 것이 아닌가?
Monica와의 가벼움 경주

15
"정의되지 않은 동작"이 아닐 수도 있습니다. Pacman이 순수 어셈블리로 작성된 경우 코드는 완전히 정의 된 방식으로 정확히 지시 된대로 수행됩니다. 정의되지 않은 동작이 아니라 버그 일뿐입니다. 따라서 코드는 기본 칩셋의 완벽한 포트가있는 모든 시스템에서 실행되는 것과 동일한 방식으로 실행됩니다.
로봇 고트

@StevenBurnap : 맞습니다.
Monica와의 가벼움 경주

@black 'kill'과 'terminate'의 차이점은 무엇입니까? 'kill'이 일반적으로 UNIX 어휘이고 'terminate'가 더 많은 Windows-y라는 사실 외에는?
Brandin

24

이 용어들 중 어느 것도 어셈블리 언어로 프로그래밍되어 메모리 보호 하드웨어 나 운영 체제의 이점없이 실행되는 아케이드 게임의 버그에는 적합하지 않습니다.

"정의되지 않은 행동"은 1989 년 C 표준위원회에 의해 만들어진 C 및 관련 언어의 최첨단 기술입니다. 언어 사양 무엇을 것인지 정의하지 않으면 코드는 정의되지 않은 동작을합니다 . Z80 어셈블리 언어에는 그러한 것이 없습니다. 가능한 모든 입력으로 모든 opcode의 효과가 잘 정의되어 있습니다. "정의되지 않은 행동"이라는 일반적인 영어의 의미를 적용하여 읽을 수 있습니다. 킬 화면은 게임을 작성한 사람들이 정의하지 않은 행동입니다. 그러나이 문맥에서는 잘못 사용할 가능성이 너무 커서이를 사용하지 않을 것입니다. 인상.

"세그먼트 결함"은 궁극적으로 PDP 시스템 프로그래밍 전문 용어에서 파생 된 POSIX의 최첨단 기술입니다. 프로그램이 어떤 것에 "매핑되지 않은"메모리 주소에 액세스하려고 할 때 세그먼테이션 결함이 발생합니다. 하드웨어와 운영 체제가이를 감지하고 오작동하는 프로그램을주의 깊게 정의하여 프로그램을 복구 할 수있는 방법으로 종료합니다 . 뭔가 같은Pac-Man 회로 보드는 ROM, RAM 및 주변 장치로 Z80의 64kB 주소 공간의 절반보다 약간만 채우므로 Pac-Man 게임 프로그램의 버그로 인해 발생할 수 있습니다. 소프트웨어가 매핑되지 않은 메모리에 액세스하려고 시도한 경우 실제 하드웨어가 수행 할 작업을 찾을 수 없었습니다. 그것은 할 것 무엇이든 (그것도 정도 팩맨의 "운영 체제"때문에,하지만, 그것은 "분할 오류"로 설명하기 부적합 할 수 있다 하나)입니다 하지 다시, 유닉스의 구현하며, 잘못된 인상을 줄 것입니다.

한편 256 레벨 버그는 매핑되지 않은 메모리에 액세스 하지 않으므로 문제가 발생합니다.

게임에 256 레벨로 넘어갈 때 나타나는 버그 가 있다고 말하는 것이 정확합니다. 또한 버그의 근본 원인은 정수 오버플 로이며 그 결과는 메모리 손상 (또는 이와 동등한 위반) 이라고 말하는 것이 정확합니다 의 메모리 및 유형 안전 ). 이는 특정 언어 또는 OS 환경을 참조하지 않고 정의 된 모든 범용 CS 용어입니다.

그것은 관찰하는 것이 정확 효과 메모리 손상 버그의 현대적인 환경에서, 버그가 효과와 유사 하지 않는 세그먼트 오류를 유발. 당신은 어떤 읽으면 프로젝트 제로 writeups을 악용, 당신은 돈 스 '에 놀라운 유사성을 볼 수 팩맨을 죽일 화면의 분석 .

팩맨 ROM을 공급할 때 킬 화면을 충실하게 재현하지 못하는 에뮬레이터는 게임 하드웨어를 올바르게 에뮬레이션하지 않습니다.


"정의되지 않은 행동"이라는 문구는 1989 년 이전의 정확한 방식으로 인쇄에 사용되지 않았을 수도 있지만, 그 문구가 묘사하는 아이디어는 프로그래밍 그 자체만큼 오래되었습니다. Common Lisp : The Language (Digital Press, 1984; ISBN 0-932376-41-X)는 "오류입니다"라는 단어를 정확히 같은 의미로 사용했습니다. 예를 들어, "x <0으로이 함수를 호출하는 것은 오류입니다"라는 의미는 프로그래머가 x <0으로 함수를 호출 할 수 없어야하고 구현자가 문자 그대로 수행 할 수있는 모든 것을 수행 할 수 있음을 의미 했습니다. 응용 프로그램 프로그래머가 준수하지 않았습니다.
Solomon Slow

5
@jameslarge 나는 당신이 무엇을 의미하는지 이해하지만, 여전히 Pac-Man 에이 개념을 적용하는 것은 실수라고 생각합니다. 게임이 디자이너가 의도 한대로 동작하지 않기 때문에 킬 화면이 버그 라고 말할 수 있습니다 . 우리는 게임이 정의되지 않은 행동 을 일으켰다 고 말할 수 없다 . 왜냐하면 어떤 상황에서도 프로그래머가 X 값에 대해 X를 할 수는 없다고 말하는 언어 사양이 없기 때문이다. 아케이드 게임 많이 사람들을 사용하고 그들 모두가 예측 가능한 효과를 AFAIK).
zwol

1
이것이 가장 좋은 대답입니다. "정의되지 않은 동작"은 코더가 표준에 따라 결과를 예측할 수없는 코드를 작성했음을 의미합니다. 만약 Pacman이 Z80 어셈블리로 작성 되었다면 (그리고 그것이 믿었다), 작성된 코드는 프로그램이 코더가 의도하지 않은 것을 수행했는지에 관계없이 완전히 정의 된 의미를가집니다.
로봇 고트

8

Pac Man의 레벨 256 버그는 프로그램 이 의도 한 테이블의 끝을 넘어서도 여전히 읽을 수있는 데이터를 읽고 프로그램 이 쓰려고하는 영역 을 넘어서서 화면의 일부에 쓰도록합니다. 여전히 프로그램이 쓸 수있는 화면 영역 내에서 . 다른 메모리 영역은 영향을받지 않습니다.

버그가 게임을 재생할 수 없게 만드는 이유는 기계가 화면의 내용을 검토하여 플레이어가 점을 먹는시기를 결정하고 플레이어가 244 개의 점을 먹었을 때 레벨이 완료된 것으로 결정하기 때문입니다. 화면의 일부를 덮어 쓰면 버그로 인해 플레이어가 244 도트를 먹을 수 없습니다. 결과적으로, 게임은 레벨을 완료 한 것으로 플레이어를 신용하지 않고 화면을 점으로 다시로드하지 않습니다.


1
256 레벨에서 자살하면 점이 다시 나타나지만지는 않습니다.
Ave

@ardaozkal : 레벨 그리기 루틴은 100 개 이상의 점을 지우고 몇 개를 그립니다. 만약 플레이어가 충분한 생명을 가지고 있다면, 결국 레벨을 향상시키기에 충분한 점을 먹을 수 있지만 30 명 이상의 생명이 필요합니다.
supercat

플레이어가 충분한 삶을 살았던 비디오를 시청 한 것을 기억하고 그가 관리 했습니다 .
Ave

@ardaozkal : 레벨을 클리어하기 위해 얼마나 많은 생명이 필요하며, 플레이어가 수정되지 않은 머신 에서 얼마나 많은 생명을 얻을 수 있습니까?
supercat

수정되지 않은 컴퓨터에서는 256 레벨까지 도달 할 수 없습니다.
Ave

1

전에 말했듯이 그것은 세그 결함이 아닙니다. 문제가 발생하는 이유를 추가하겠습니다 . 오버플로 입니다.

레벨 번호는 바이트에 저장되므로 범위는 0-255입니다. 레벨을 완료 할 때마다 카운터가 증가합니다. 수준 256에서 오버플로로 인해 카운터는 실제로 0입니다.

그러나 게임은 레벨의 맨 아래에 과일을 표시하려고 시도합니다. 과일 수 / 유형은 수준에 따라 다릅니다. 공식은 레벨 8에서 완료된 레벨 당 하나의 과일을 표시합니다. 카운터에 따르면 레벨 0에서 8까지 있습니다. 테스트는 참이며 255 개의 과일 (이전 레벨 값)을 인쇄해야합니다. 어느 것이 불가능 하며이 결함이있는 화면을 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.