Я пытаюсь объяснить кому-то ошибки сегментации, и я размышлял об уровне экрана уничтожения 256 в Pacman, и о том, как он вызывается целочисленным переполнением, и о том, как поведение похоже на «неизвестное состояние», часто описываемое в сегментации неисправность.
Я хочу сказать, что это хороший пример того, что я называю «необработанным сегфоутом», но я бы предпочел получить второе мнение, прежде чем распространять дезинформацию.
Я попытался найти его, но все, что я получаю, это документы о самой ошибке, а также о том, что произошло между Hipster Whale и Namco.
Итак, считаете ли вы поведение на уровне 256 Пакмана примером необработанного нарушения сегментации?
Ответы:
Точно нет.
Доступ к адресу памяти, который вы не выделяли, всегда является ошибкой программирования. И действие на информации, которую вы получаете от нее, приводит к неопределенному поведению, это очень точно. Я понятия не имею, для какой платформы был написан оригинальный Pac-man, но я почти уверен, что он демонстрировал это поведение, как и любая другая машина фон Неймана.
Тем не менее, «ошибка сегментации» является техническим термином для гораздо более конкретного условия. Это происходит, когда компьютер автоматически обнаруживает, что это произошло, и завершает процесс, а не допускает неопределенного поведения. Для этого требуется специальная (сегментированная) модель памяти со сложными тегами владения. Я не думаю , что 1980 аркадных игр было что, и в самом деле поведение игры предполагает , что ошибка была не обнаружена, и неопределенное поведение было произойти.
источник
Похоже, вы путаете «неопределенное поведение» и «ошибка сегментации».
Не существует такого понятия, как необработанное сегфо. Ошибка сегментации - обработка ошибок по определению.
Если у вас нет ОС, которая обнаружила плохой доступ к памяти и остановила процесс в целях безопасности, то у вас нет ошибки сегментации.
Во всяком случае, это довольно хороший пример того, как UB не всегда приводит к segfault.
источник
Ни один из этих терминов не подходит для ошибки в аркадной игре, которая была запрограммирована на ассемблере и работает без использования аппаратных средств защиты памяти или операционной системы.
«Неопределенное поведение» - это термин «искусство» на C и родственных языках, разработанный Комитетом по стандартам C еще в 1989 году. Код имеет неопределенное поведение, когда спецификация языка не определяет, что он будет делать. В ассемблере Z80 такого нет: эффект каждого кода операции с каждым возможным вводом четко определен. Общепринятое английское значение «неопределенного поведения» можно прочитать, чтобы применить - экран уничтожения - это поведение, не определенное людьми, которые написали игру, - но я бы не стал использовать его в этом контексте, потому что это слишком вероятно, чтобы дать неверное представление впечатление.
«Ошибка сегментации» - это современный термин в POSIX, полученный в конечном итоге из жаргона программирования системы PDP. Ошибки сегментации возникают, когда программа пытается получить доступ к адресу памяти, который ни на что не «привязан»: аппаратное обеспечение и операционная система обнаруживают это и закрывают неисправную программу тщательно определенным способом, который дает программе возможность восстановить , Что-то вродеэто могло произойти из-за ошибки в игровой программе Pac-Man, потому что печатная плата Pac-Man заполняет чуть менее половины 64-килобайтного адресного пространства Z80 ПЗУ, ОЗУ и периферийными устройствами, но у меня нет Я не смог выяснить, что будет делать реальное оборудование, если оно попытается получить доступ к неотображенной памяти. Что бы это ни делало, это было бы неуместно называть «ошибкой сегментации», потому что «операционная система» для Pac-Man (в той степени, в которой она даже есть ) не является реализацией Unix и, опять же, она даст неправильное впечатление.
Между тем, ошибка уровня 256 не позволяет получить доступ к неотображенной памяти, поэтому это спорный вопрос.
Можно с уверенностью сказать, что в игре есть ошибка, которая проявляется при переходе на уровень 256. Также можно с уверенностью сказать, что основной причиной ошибки является целочисленное переполнение и что ее последствия - повреждение памяти (или, что то же самое, нарушение из памяти и безопасности типа ). Все это термины CS общего назначения, определенные без ссылки на какой-либо конкретный язык или среду ОС.
Точно также можно заметить, что последствия ошибки аналогичны последствиям в современной среде ошибок повреждения памяти, которые не вызывают ошибок сегментации. Если вы прочтете какие-либо описания эксплойтов Project Zero , вы увидите замечательное сходство с анализом Дона Ходжеса экрана убийства Pac-Man .
Обратите внимание, что эмулятор, который точно не воспроизводит экран уничтожения при загрузке ПЗУ Pac-Man, неправильно эмулирует игровое оборудование.
источник
Ошибка уровня 256 в Pac Man приводит к тому, что программа читает данные, которые находятся за пределами предполагаемой таблицы, но все еще остается читаемым хранилищем , и записывает в те части экрана, которые находятся за пределами тех, которые программа намеревается записать, но все еще хорошо в тех областях экрана, которые разрешено писать программе . Другие области памяти не затрагиваются.
Причина, по которой ошибка делает игру непригодной для игры, состоит в том, что машина определяет, когда игрок ест точки, изучая то, что на экране, и решает, что уровень завершен, когда игрок съел 244 точки. Перезаписывая часть экрана, ошибка делает невозможным для игрока съесть 244 точки; следовательно, игра никогда не даст игроку возможность пройти уровень и перезагрузит экран точками.
источник
Как уже говорилось, нет, это не ошибка сегмента. Я добавлю, почему проблема возникает: это переполнение .
Номер уровня хранится в байте, поэтому диапазон составляет 0-255. Каждый раз, когда вы проходите уровень, счетчик увеличивается. На уровне 256 счетчик фактически равен 0 из-за переполнения.
Однако в игре постарайтесь отобразить некоторые фрукты в нижней части уровня. Количество / тип плодов зависит от уровня. Формула отображает один фрукт на готовый уровень ниже уровня 8. Согласно счетчику вы находитесь на уровне 0, то есть ниже уровня 8. Тогда тест верен, и вы должны напечатать 255 фруктов (старое значение уровня). Что невозможно и дает этот сбойный экран.
источник