Чи можна вважати «помилку рівня 256» в грі Pacman нечестованою сегсторією?


51

Я намагаюся пояснити комусь недоліки сегментації, і я думав про рівень екрана 256 вбивства в Pacman, і про те, як це викликається переповненням цілого числа, і наскільки подібна поведінка часто описана в сегментації до "невідомого стану". вина.

Я хочу сказати, що це хороший приклад того, що я називаю "необробленим сегментом", але я скоріше отримаю другу думку, перш ніж потенційно поширюватимуть дезінформацію.

Я спробував роздивитися це, але все, що я отримую, - це документи про саму помилку, а також співпраця між Hipster Whale та Namco.

Отже, чи вважаєте ви поведінку на рівні 256 Пакмана прикладом неузгодженого порушення сегментації?


3
Ось точний опис помилки разом із виправленням для виправлення: donhodges.com/how_high_can_you_get2.htm
abligh

26
Помилки сегментації підвищуються апаратними засобами, щоб уникнути незаконного доступу до пам'яті. Я не фахівець з Pacman, але апаратне забезпечення, на яке він працював, майже напевно не мав цієї функції безпеки.
BlueRaja - Danny Pflughoeft

3
Згідно з wikipedia Pacman використовував Z80. Z80-ті точно не мали захисту пам’яті.
Gort the Robot

Це не сегментарно - у системі не було жодної форми захисту пам'яті. Несправність Pac-Man відчуває на рівні 256 є просто целочисленное переповнення, некоректно обробляється код гри.
bwDraco

3
FYI, я не думаю, що це кваліфікується як помилка. Помилка - це поломка або помилка в комп'ютерній програмі або системі, що спричиняє неправильний або несподіваний результат, або поводиться ненавмисно. Це було навмисно запрограмовано таким чином, оскільки відчувалося, що ніхто не досягне цього рівня. Насправді його просто поганий дизайн програмного забезпечення.
Келтарі

Відповіді:


113

Точно ні.

Доступ до адреси пам'яті, яку ви не виділили, - це завжди помилка програмування. І діючи на інформацію, яку ви отримуєте з неї, виробляється невизначена поведінка, що багато чого є точним. Я не маю уявлення, для якої платформи був написаний оригінальний Pac-man, але я впевнений, що він проявляв таку поведінку, як і будь-яка інша машина фон Неймана.

Однак "помилка сегментації" - це технічний термін для набагато конкретнішого стану. Це відбувається, коли комп’ютер автоматично виявляє, що це сталося, і припиняє процес, а не допускає виникнення невизначеної поведінки. Для цього потрібна конкретна (сегментована) модель пам’яті зі складними тегами власності. Я не думаю , що 1980 аркадних ігор було що, і справді поведінку гри передбачає , що помилка була НЕ виявлено, і невизначене поведінку було статися.


19
@ B1KMusic: Ви справді запитуєте "чи цей код" помилка "- приклад виклику невизначеної поведінки через доступ до пам'яті поза межами", і відповідь "так". Будь-які раціоналізатори щодо лову, ігнорування та не отримання сигналу SIGSEGV просто заплутують питання.
Гонки легкості з Монікою

5
@ B1KMusic не всі перевиконання буфера призводять до сегмента за замовчуванням. Це залежить від того, як була розподілена пам'ять. Якщо пам'ять буде виділена статично (один великий буфер розведений вручну в різних зонах), а область, що знаходиться безпосередньо за останнім рівнем, використовувалася для чогось (наприклад, графіки спрайтів), вона не буде сегментуватись.
храповик виродка

6
Ці старі аркадні системи використовували примітивні ОС, які давали грі майже повний контроль над апаратним забезпеченням, подібно до ранніх версій DOS. Ідея сегмента за типом архітектури такого типу не є стартером, оскільки передбачає, що один запущений процес (Pac-Man) не володіє всією пам'яттю. Для отримання додаткової інформації можна прочитати проект MAME та його історію.

20
Невизначена поведінка не є властивістю машин фон Неймана, це властивість C, мови програмування. Програми, написані мовою складання, не можуть виявляти невизначеної поведінки, оскільки поведінка інструкцій з мови збірки завжди чітко визначена (навіть якщо результати іноді не визначені).
Дітріх Епп

8
@Snowman немає такого шару на машині Pac-Man. Немає завантажувача - гра знаходиться в ROM, який виконується на місці. Немає управління пам’яттю - все статично. Немає "послуг"; гра отримує доступ до обладнання безпосередньо, і в системі немає байта коду, який не входить до гри, а написаний для гри.
варення

38

Схоже, ви плутаєте "невизначену поведінку" та "помилку сегментації".

Немає такого поняття, як необроблений сегмент за замовчуванням. Помилкою сегментації є обробка помилок за визначенням.

Якщо у вас немає ОС, яка б виявила поганий доступ до пам’яті та припинила процес для безпеки, то у вас немає помилки сегментації.

Якщо що, то це досить хороший приклад того, як UB не завжди призводить до сегментації.


2
Якщо бути точним, ОС може вирішити вбити (тобто безповоротно) процес. Натомість сучасні ОС вважають за краще скасувати її, яка може бути спіймана та оброблена FWIW.
edmz

@black: Хіба це не я сказав?
Гонки легкості з Монікою

15
Це може бути навіть не "невизначена поведінка". Якщо Pacman був написаний чистою збіркою, то код робив саме те, що було сказано робити в абсолютно визначеному вигляді. Не визначена поведінка, а просто помилка. Таким чином, код би виконувався точно так само, як і в будь-якій системі, яка мала ідеальний порт базового чіпсета.
Гурт Робота

@StevenBurnap: Це правда.
Гонки легкості з Монікою

@black Яка різниця між "вбити" та "припинити"? Крім того, що "убивати" - це звичайно словник UNIX, а "закінчувати" - це більше Windows-y?
Брандін

24

Жоден із цих термінів не підходить для помилки в аркадній грі, запрограмованій мовою асемблера та працює без використання апаратного забезпечення або операційної системи.

«Невизначена поведінка» є мистецтво термін-оф-в C і споріднених мовах, придуманий комітетом по стандартам C ще в 1989 році Кодексу визначено поведінку , коли специфікація мови не визначає , що він буде робити. У мові складання Z80 такого немає. Ефект кожного опкоду при кожному можливому введенні чітко визначений. Традиційне англійське значення "невизначеної поведінки" можна прочитати, щоб застосувати - екран вбивства - це поведінка, не визначена людьми, які написали гру - але я б не використовував це в цьому контексті, оскільки це занадто ймовірно, щоб дати неправильне враження.

"Помилка сегментації" - це технологія POSIX, отримана в кінцевому підсумку від жаргону програмування системи PDP. Помилки сегментації трапляються, коли програма намагається отримати доступ до адреси пам'яті, яка ні на що не "відображена": апаратне забезпечення та операційна система виявляють це і вимикають несправну програму, ретельно визначеним способом, що дозволяє програмі отримати можливість відновитись . Щось подібнеце могло статися внаслідок помилки в ігровій програмі Pac-Man, тому що плата Pac-Man заповнює лише трохи менше половини 64-кбайтного простору адреси Z80 за допомогою ROM, RAM та периферійних пристроїв, але я не маю ' я не змогла дізнатися, що робитиме справжнє обладнання, якби програмне забезпечення намагалося отримати доступ до незробленої пам'яті. Що б це не робило, було б недоцільно описувати як "помилку сегментації", оскільки "операційна система" для Pac-Man (наскільки вона навіть має ) не є реалізацією Unix і, знову ж таки, це створило б неправильне враження.

Рівень 256 помилка, тим часом, ніяк НЕ отримати доступ до неотображённие пам'яті, так що це спірне питання.

Точно можна сказати, що в грі є помилка, яка виявляється при переході до рівня 256. Також точно сказати, що першопричиною помилки є ціле переповнення , і що її наслідками є пошкодження пам'яті (або, що рівнозначно, порушення) з пам'яті і безпеки типу ). Це всі терміни CS загального призначення, визначені без посилання на якусь конкретну мову чи середовище ОС.

Також точно зауважити, що наслідки помилки подібні до наслідків помилок із пошкодженням пам’яті, які не провокують помилки сегментації , в сучасних умовах . Якщо ви прочитаєте будь-які описи експлуатації Project Zero , ви побачите неабияку схожість з аналізом Дон Ходжеса екрана вбивства Pac-Man .

Зауважте, що емулятор, який не відтворює вірно екрана вбивства під час подачі ПЗУ Pac-Man, неправильно імітує ігрове обладнання.


Фраза "невизначена поведінка", можливо, не була використана в друку саме таким чином до 1989 року, але думка, яку ця фраза описує, така ж стара, як і саме програмування. Common Lisp: Мова (Digital Press, 1984; ISBN 0-932376-41-X) використовувала слова "це помилка", щоб означати саме те саме. Наприклад, "Помилково викликати цю функцію з x <0" означало, що програміст не повинен дозволяти викликати функцію з x <0, і що реалізація дозволяла робити буквально все, що хотів, щоб виконавець хотів це зробити, якщо прикладний програміст не виконав.
Соломон повільно

5
@jameslarge Я розумію, що ти маєш на увазі, але я все ще думаю, що помилково застосовувати цю концепцію до Pac-Man. Можна сказати, що екран вбивства - це помилка, оскільки гра явно не веде себе так, як планував дизайнер. Ми не можемо сказати, що гра спровокувала невизначену поведінку , тому що немає жодної мовної специфікації, яка б сказала "ні за яких обставин програміст не може робити X" для будь-якого значення X. (Я вважаю, що використання недокументованих опдодів Z80 може бути кваліфікованим, за винятком цього багато аркадних ігор було використовувати ті , і AFAIK всі вони мають передбачувані наслідки).
zwol

1
Це найкраща відповідь. "Не визначена поведінка" означає, що кодер написав код, результат якого не може бути передбачений на основі стандарту. Якщо Pacman написаний у збірці Z80 (і я вважаю, що це було), то написаний код мав цілком визначене значення незалежно від того, чи робила програма те, що кодер не мав наміру.
Gort the Robot

8

Помилка рівня 256 в програмі Pac Man призводить до того, що програма зчитує дані, що знаходяться поза кінцем призначеної таблиці, але все ще читає сховище та записує на частини екрану, які виходять за рамки тих, які програма має намір записати, але є все ще знаходяться в тих областях екрану, які програма може дозволити записувати . Ніякі інші області пам’яті не зачіпають.

Причина того, що помилка робить гру неспроможною, полягає в тому, що машина визначає, коли гравець їсть крапки, досліджуючи, що на екрані, і вирішує, що рівень закінчується, коли гравець з'їв 244 точки. Перезаписуючи частину екрана, помилка унеможливлює зйомку гравця 244 крапки; отже, гра ніколи не буде кредитувати гравця за виконання рівня та перезавантаження екрана крапками.


1
Коли ви вбиваєте себе на рівні 256, точки відроджуються, але ви нічого не втрачаєте.
пр.

@ardaozkal: Рутинна схема малювання за рівнем стирає більше 100 крапок і малює кілька. Якби гравцеві було достатньо життів, врешті-решт можна було б з'їсти достатньо крапок, щоб просунути рівень, але це вимагало б більше 30 життів.
supercat

Пам’ятаю, переглядав відео, де гравцеві було достатньо життів, і він ним керував… і я просто знайшов це .
пр.

@ardaozkal: Скільки життів потрібно, щоб очистити рівень, і скільки життів може отримати гравець на немодифікованій машині?
supercat

На немодифікованій машині ви навіть не можете досягти рівня 256.
пр.

1

Як було сказано раніше, це не провина. Додам, чому виникає проблема: це перелив .

Номер рівня зберігається в байті, тому діапазон становить 0-255. Кожен раз, коли ви виконуєте рівень, лічильник збільшується. На рівні 256 лічильник насправді дорівнює 0 через переповнення.

Однак у грі спробуйте відобразити деякі фрукти на дні рівня. Кількість / тип фруктів залежить від рівня. Формула відображає один плід на готовий рівень під рівнем 8. За лічильником, ви знаходитесь на рівні 0, так що нижче 8. Тест є вірним, тоді ви повинні надрукувати 255 фруктів (старе значення рівня). Що неможливо, і дає цей засклений екран.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.