정보

[오류 속 통찰] 세이브 데이터를 날려버리는 플스 컨트롤러

키워드 팔로워 2023. 7. 5. 12:49

요약

1. 플스 출시 전 Crash Bandicoot이라는 프로그램을 개발하던 중 세이브/로드 중 데이터가 날아가는 현상 발견

2. 코드가 누더기가 될 때까지 해체해서 확인 했으나, 원인을 파악하지 못함.

3. 플스의 타이머 기본값이 100Hz인데 반해 이 게임에서는 정교한 구현을 위해 1000Hz로 설정했었음.

4. 100 Hz로 바꾸자 오류가 발생하지 않게됨. (게임 구동시 1000Hz로 돌리다가 save/load 시에만 100Hz로 바꿈)

5. 하드웨어 문제라는 확신이 들어 다양한 테스트를 해봤고, 1000Hz에서 컨트롤러를 사용하는 조건에서 문제가 생긴다는 걸 확인함.

6. 소니에 하드웨어 문제 가능성을 타진 하였으나, 그럴리 없다는 답변을 비공식적으로 받음.

7. 소니에 해당 문제가 발생할 수 있는 테스트 코드를 주고나서야 문제가 확인됨. 컨트롤러와 메모리카드가 동시에 빠른 속도로 데이터가 전송 되면 데이터가 손실되는 현상이 있었음.

=> 설계 하는 입장에서는 모든 요건을 통제하고 있다는 착각이 드는 경우가 많다. 내가 열심히 했으면 했을 수록 더...

하지만 항상 덜 처 맞을 뿐이지 불의의 일격을 피하기란 쉽지 않다.

번역본 (DeepL)

더보기

이 일을 다시 떠올리는 것은 고통스럽습니다. 프로그래머는 첫 번째, 두 번째, 세 번째로 코드를 탓하는 법을 배우게 되고, 10,000번째쯤 되면 컴파일러를 탓하게 됩니다. 그 다음에는 하드웨어를 탓하게 됩니다. 이것이 제 하드웨어 버그 이야기입니다.

 무엇보다도 저는 크래시 밴디쿳의 메모리 카드(로드/저장) 코드를 작성했습니다. 잘난 척하는 게임 코더에게 이것은 공원 산책하는 것과 같아서 며칠이 걸릴 것으로 예상했습니다. 결국 6주 동안 코드를 디버깅했습니다. 그 기간 동안 다른 일도 했지만 며칠에 몇 시간씩 이 버그로 계속 돌아왔어요. 정말 괴로웠죠.

 진행 상황을 저장하려고 하면 메모리 카드에 액세스하는 증상이 나타났고, 거의 모든 경우 정상적으로 작동했습니다. 하지만 가끔씩 뚜렷한 이유 없이 쓰기나 읽기가 시간 초과되는 경우가 있었습니다. 짧게 쓰면 메모리 카드가 손상되는 경우가 많았습니다. 플레이어가 저장을 하러 가면 저장되지 않을 뿐만 아니라 메모리 카드가 지워지곤 했습니다. 오, 이런.

 얼마 후 소니의 프로듀서인 코니 부스는 당황하기 시작했습니다. 이 버그로는 게임을 출시할 수 없었고, 6주가 지난 후에도 문제가 무엇인지 전혀 파악하지 못했습니다. 코니를 통해 다른 PS1 개발자들에게 이 사실을 알렸습니다. 혹시 이런 문제를 본 사람이 있나요? 아무도 없었어요. 메모리 카드 시스템에 문제가 있었다는 사람은 아무도 없었습니다.

 디버깅 아이디어가 부족할 때 할 수 있는 유일한 방법은 분할과 정복입니다. 문제가 있는 프로그램의 코드를 점점 더 많이 제거하여 문제를 나타내는 비교적 작은 부분만 남을 때까지 계속 제거하는 것입니다. 버그가 있는 부분만 남을 때까지 계속 부분을 잘라내는 것입니다.

 비디오 게임과 같은 맥락에서 이 방법의 문제점은 조각을 제거하기가 매우 어렵다는 것입니다. 게임에서 중력을 시뮬레이션하는 코드를 제거해도 게임을 계속 실행하려면 어떻게 해야 할까요? 아니면 캐릭터를 렌더링하는 코드도요?

 전체 모듈을 실제 작업을 수행하는 척하지만 실제로는 버그가 발생하지 않는 완전히 사소한 작업을 수행하는 스텁으로 대체해야 합니다. 작동을 유지하려면 새로운 스캐폴딩 코드를 작성해야 합니다. 느리고 고통스러운 과정입니다.

 간단히 말해서 저는 이렇게 했습니다. 게임을 실행하기 위해 시스템을 설정하고 렌더링 하드웨어를 초기화하는 코드 등 시작 코드만 남을 때까지 점점 더 많은 코드를 제거했습니다. 물론 그 당시에는 그래픽 코드를 모두 제거했기 때문에 로드/저장 메뉴를 표시할 수 없었습니다. 하지만 사용자가 (보이지 않는) 로드/저장 화면을 사용하여 저장을 요청한 다음 카드에 쓰는 것으로 가정할 수 있었습니다.

 결국에는 아주 적은 양의 코드에서 문제가 발생했지만 여전히 무작위로 발생했습니다! 대부분의 경우 작동했지만 가끔씩 실패하기도 했습니다. 실제 크래시 코드는 거의 모두 제거했지만 여전히 이런 일이 발생했습니다. 정말 당황스러웠습니다. 남아 있는 코드가 실제로는 아무것도 작동하지 않았기 때문입니다.

 어느 순간 - 아마 새벽 3시였을 것입니다 - 한 가지 생각이 떠올랐습니다. 읽기 및 쓰기(I/O)에는 정확한 타이밍이 필요합니다. 하드 드라이브, 컴팩트 플래시 카드, 블루투스 송신기 등 그 대상이 무엇이든 간에 읽고 쓰는 로우레벨 코드는 시계에 따라 작동해야 합니다.

 클럭은 CPU에 직접 연결되지 않은 하드웨어 장치가 CPU가 실행 중인 코드와 동기화 상태를 유지할 수 있게 해줍니다. 클록은 데이터가 한 쪽에서 다른 쪽으로 전송되는 속도인 전송 속도를 결정합니다. 타이밍이 엉망이 되면 하드웨어나 소프트웨어, 또는 둘 다 혼동될 수 있습니다. 이는 매우 심각한 문제이며 일반적으로 데이터 손상을 초래합니다.

 설정 코드의 무언가가 어떻게든 타이밍을 망치고 있다면 어떨까요? 테스트 프로그램의 타이밍 관련 코드를 다시 살펴본 결과 PS1의 프로그래밍 가능한 타이머를 1kHz(초당 1000틱)로 설정한 것을 발견했습니다. PS1을 시작할 때 기본 상태에서는 100Hz 정도에서 실행되었기 때문에 비교적 빠른 속도입니다. 따라서 대부분의 게임에서는 이 타이머가 100Hz로 실행됩니다.

 이 게임의 리드 개발자이자 유일한 개발자인 Andy는 Crash의 모션 계산을 더 정확하게 하기 위해 타이머를 1kHz로 설정했습니다. 앤디는 과한 것을 좋아하며, 중력을 시뮬레이션하려면 가능한 한 정밀도를 높여야 한다고 생각했습니다.

 하지만 이 타이머를 늘리면 프로그램의 전체 타이밍과 메모리 카드의 전송 속도를 설정하는 데 사용되는 시계에 방해가 된다면 어떨까요?

 타이머 코드에 주석을 달았습니다. 다시는 오류가 발생하지 않았습니다. 하지만 그렇다고 해서 문제가 해결된 것은 아니었고 이 문제는 무작위로 발생했습니다. 제가 운이 좋았던 걸까요?

 며칠이 더 지나면서 저는 테스트 프로그램을 계속 사용했습니다. 버그는 다시는 발생하지 않았습니다. 전체 크래시 코드 베이스로 돌아가서 로드/저장 코드를 수정하여 메모리 카드에 액세스하기 전에 프로그래밍 가능한 타이머를 기본 설정(100Hz)으로 재설정하고, 이후에는 1kHz로 다시 설정했습니다. 그 후 다시는 읽기/쓰기 문제가 발생하지 않았습니다.

 

 하지만 왜 그럴까요?

 

 타이머를 1kHz로 설정했을 때 발생하는 오류의 패턴을 찾기 위해 테스트 프로그램을 반복해서 돌려보았습니다. 결국, 누군가가 PS1 컨트롤러로 플레이할 때 오류가 발생한다는 것을 알아냈습니다. 로드/저장 코드를 테스트할 때 컨트롤러를 가지고 노는 경우는 거의 없었기 때문에 - 왜 컨트롤러를 가지고 노는 걸까요? -- 라는 생각에 눈치채지 못했죠. 그런데 어느 날 아티스트 중 한 명이 테스트가 끝나기를 기다리는데 - 당시에는 제가 욕을 하고 있었을 겁니다 - 초조하게 컨트롤러를 만지작거리고 있었습니다. 실패했습니다. "잠깐, 뭐라고요? 야, 다시 해봐!"

 메모리 카드에 쓰기 시작, 컨트롤러 흔들기, 메모리 카드 손상이라는 두 가지가 서로 연관되어 있다는 인사이트를 얻은 후에는 쉽게 재현할 수 있었습니다. 확실히 하드웨어 버그처럼 보였습니다.

 저는 코니에게 돌아가서 제가 발견한 사실을 이야기했습니다. 그녀는 PS1을 설계한 하드웨어 엔지니어 중 한 명에게 이 사실을 전달했습니다. "불가능합니다." 코니는 이렇게 말했습니다. "하드웨어 문제일 리가 없죠." 저는 그녀에게 그와 통화할 수 있는지 물어보라고 했습니다.

 그는 저에게 전화를 걸었고, 그의 서툰 영어와 저의 (극도로) 서툰 일본어로 우리는 논쟁을 벌였습니다. 결국 저는 "컨트롤러를 흔들면 작동하는 30줄짜리 테스트 프로그램을 보내드리겠습니다."라고 말했습니다. 그는 물러섰습니다. 그는 시간 낭비일 뿐 아니라 새 프로젝트로 매우 바빴지만 우리가 소니의 매우 중요한 개발자였기 때문에 약속을 지키겠다고 했습니다. 저는 작은 테스트 프로그램을 정리해서 보냈습니다.

 다음날 저녁(우리는 LA에 있었고 그는 도쿄에 있었기 때문에 다음날 그가 왔을 때는 저녁이었어요) 그는 저에게 전화를 걸어 수줍게 사과했습니다. 하드웨어 문제였다고요.

 정확한 문제가 무엇인지 확실히 알 수는 없었지만, 소니 본사에서 들은 바에 따르면 프로그래밍 가능한 타이머를 충분히 높은 클럭 속도로 설정하면 타이머 크리스탈 근처의 마더보드에 있는 장치와 간섭을 일으킬 수 있다는 것이었습니다. 이러한 것 중 하나는 메모리 카드의 전송 속도 컨트롤러로, 컨트롤러의 전송 속도도 설정합니다. 저는 하드웨어 전문가가 아니기 때문에 자세한 내용은 잘 모르겠습니다.

 하지만 요점은 마더보드의 개별 부품 간에 누화가 발생하고 타이머를 1kHz로 실행하면서 컨트롤러 포트와 메모리 카드 포트를 통해 데이터를 전송하면 비트가 떨어지고 데이터가 손실되어 카드가 손상된다는 것이었습니다.

출처

 

Crash Bandicoot ― Andreas Zwinkau

Source: Dave Bagget It's kind of painful to re-live this one. As a programmer, you learn to blame your code first, second, and third... and somewhere around 10,000th you blame the compiler. Well down the list after that, you blame the hardware. This is my

beza1e1.tuxen.de

목록

 

[오류 속 통찰] 개요 목차

미드 하우스의 하우스 박사는 진단이 어려운 환자들을 다양한 방법과 시각으로 어떤 병을 가지고 있는지 밝혀 낸다. 때로는 아무런 연관이 없어 보이는 것들도 상호작용을 통해 예측불가한 결

keywordfollower.tistory.com