¿Se puede considerar el "error de nivel 256" en el juego de Pacman como un defecto predeterminado no manejado?

51

Estoy tratando de explicar las fallas de segmentación a alguien, y estaba pensando en la pantalla de nivel 256 en Pacman, y cómo se desencadena por el desbordamiento de enteros, y cuán similar es el comportamiento al "estado desconocido" descrito con frecuencia en una segmentación culpa.

Quiero decir que este es un buen ejemplo de lo que yo llamo un "segfault no manejado", pero prefiero obtener una segunda opinión antes de difundir información errónea.

Intenté buscarlo, pero todo lo que obtengo son documentos sobre el error en sí, así como esa colaboración entre Hipster Whale y Namco.

Entonces, ¿consideraría que el comportamiento en el nivel 256 de Pacman es un ejemplo de violación de segmentación no controlada?

Braden Best
fuente
3
Aquí hay una descripción exacta del error, junto con un parche para solucionarlo: donhodges.com/how_high_can_you_get2.htm
hasta el
26
Las fallas de segmentación son generadas por el hardware para evitar el acceso ilegal a la memoria. No soy un experto en Pacman, pero el hardware con el que funcionó casi seguro no tenía esta característica de seguridad para empezar.
BlueRaja - Danny Pflughoeft
3
Según la wikipedia, Pacman usó un Z80. Los Z80 definitivamente no tenían protección de memoria.
Gort the Robot
No es una falla predeterminada: el sistema no tenía ninguna forma de protección de memoria. La falla que Pac-Man experimenta en el nivel 256 es simplemente un desbordamiento de enteros que el código del juego no maneja correctamente.
bwDraco
3
Para su información, no creo que esto califique como un error. Un error es una falla o falla en un programa o sistema de computadora que hace que produzca un resultado incorrecto o inesperado, o que se comporte de manera no intencional. Fue programado intencionalmente de esa manera, ya que se sintió que nadie llegaría a ese nivel. En realidad, es simplemente un mal diseño de software.
Keltari

Respuestas:

113

Definitivamente no.

Acceder a una dirección de memoria que no asignó siempre es un error de programación. Y actuar sobre la información que obtienes produce un comportamiento indefinido, eso es cierto. No tengo idea de para qué plataforma se escribió el Pac-man original, pero estoy bastante seguro de que exhibió este comportamiento como cualquier otra máquina von Neumann.

Sin embargo, "falla de segmentación" es un término técnico para una condición mucho más específica. Ocurre cuando la computadora detecta automáticamente que esto sucedió y finaliza el proceso en lugar de permitir que ocurra un comportamiento indefinido. Esto requiere un modelo de memoria específico (segmentado) con etiquetado de propiedad sofisticado. No creo que los juegos de arcade de 1980 tuvieran eso, y de hecho el comportamiento del juego sugiere que no se detectó el error , y el comportamiento indefinido ocurrió.

Kilian Foth
fuente
19
@ B1KMusic: Realmente estás preguntando "¿es este 'error' del código un ejemplo de invocar un comportamiento indefinido a través del acceso a la memoria fuera de los límites?", Y la respuesta es "sí". Cualquier racionalización acerca de atrapar, ignorar, no obtener una señal SIGSEGV es simplemente un asunto confuso.
Lightness compite con Monica el
55
@ B1KMusic no todas las desbordamientos del búfer resultan en una falla predeterminada. Depende de cómo se asignó la memoria. Si la memoria está asignada estáticamente (un búfer grande dividido manualmente en diferentes zonas) y el área inmediatamente detrás del último nivel se usó para algo (como los gráficos de sprites), entonces no sería predeterminado.
monstruo de trinquete
66
Esos viejos sistemas arcade usaban sistemas operativos primitivos que le daban al juego un control casi total sobre el hardware, similar a las versiones anteriores de DOS. La idea de una falla por defecto en ese tipo de arquitectura no es un iniciador, porque supone que el proceso en ejecución (Pac-Man) no posee toda la memoria. Para obtener más información, uno puede leer sobre el proyecto MAME y su historial.
20
El comportamiento indefinido no es una propiedad de las máquinas von Neumann, es una propiedad de C, el lenguaje de programación. Los programas escritos en lenguaje ensamblador no pueden exhibir un comportamiento indefinido, porque el comportamiento de las instrucciones en lenguaje ensamblador siempre está bien definido (incluso si los resultados a veces no se especifican).
Dietrich Epp
8
@Snowman no existe tal capa en una máquina Pac-Man. No hay cargador: el juego está en ROM de ejecución inmediata. No hay administración de memoria: todo es estático. No hay "servicios"; el juego accede al hardware directamente y no hay un byte de código en el sistema que no sea parte del juego y esté escrito para el juego.
hobbs
38

Parece que estás confundiendo "comportamiento indefinido" y "falla de segmentación".

No existe tal cosa como una segfault no controlada. Una falla de segmentación es el manejo de errores, por definición.

Si no tiene un sistema operativo que detectó el mal acceso a la memoria y finalizó el proceso por seguridad, entonces no tiene una falla de segmentación.

En todo caso, entonces, este es un buen ejemplo de cómo UB no siempre resulta en una falla por defecto.

La ligereza corre con Mónica
fuente
2
Para ser precisos, el sistema operativo puede decidir matar (es decir, irrecuperable) el proceso. Los sistemas operativos modernos prefieren terminarlo , que puede ser capturado y manejado, FWIW.
edmz
@ Black: ¿No es eso lo que dije?
Lightness compite con Monica el
15
Puede que ni siquiera sea un "comportamiento indefinido". Si Pacman fue escrito en ensamblaje puro, entonces el código hizo exactamente lo que se le dijo que hiciera de una manera completamente definida. No es un comportamiento indefinido, sino simplemente un error. Como tal, el código se ejecutaría exactamente de la misma manera en cualquier sistema que tuviera un puerto perfecto del conjunto de chips subyacente.
Gort the Robot
@StevenBurnap: Eso es cierto.
Lightness compite con Monica el
@black ¿Cuál es la diferencia entre 'matar' y 'terminar'? ¿Además del hecho de que 'matar' es normalmente vocabulario UNIX y 'terminar' es más Windows-y?
Brandin
24

Ninguno de estos términos es apropiado para un error en un juego arcade que se programó en lenguaje ensamblador y se ejecuta sin el beneficio del hardware o sistema operativo de protección de memoria.

"Comportamiento indefinido" es un término de arte en C y lenguajes relacionados, acuñado por el comité de estándares C en 1989. El código tiene un comportamiento indefinido cuando la especificación del lenguaje no define lo que hará. No existe tal cosa en el lenguaje ensamblador Z80: el efecto de cada código de operación con cada entrada posible está bien definido. El significado convencional en inglés de "comportamiento indefinido" se puede leer para aplicarlo: la pantalla de matar es un comportamiento no definido por las personas que escribieron el juego, pero no lo usaría en este contexto porque es muy probable que diga mal impresión.

"Falla de segmentación" es un término de arte en POSIX, derivado en última instancia de la jerga de programación del sistema PDP. Las fallas de segmentación ocurren cuando un programa intenta acceder a una dirección de memoria que no está "asignada" a nada: el hardware y el sistema operativo lo detectan y apagan el programa que funciona mal, de una manera cuidadosamente definida que le permite al programa la oportunidad de recuperarse . Algo comoEsto podría haber sucedido como resultado de un error en el programa de juego Pac-Man, porque la placa de circuito Pac-Man solo ocupa un poco menos de la mitad del espacio de direcciones de 64kB del Z80 con ROM, RAM y periféricos, pero no tengo No he podido averiguar qué haría el hardware real si el software intentara acceder a la memoria no asignada. Sin embargo, haga lo que haga, sería inapropiado describirlo como un "fallo de segmentación", porque el "sistema operativo" para Pac-Man (en la medida en que lo tiene ) no es una implementación de Unix y, nuevamente, daría la impresión equivocada

Mientras tanto, el error de nivel 256 no accede a la memoria no asignada, por lo que es discutible.

Es exacto decir que el juego tiene un error que se manifiesta al avanzar al nivel 256. También es correcto decir que la causa raíz del error es un desbordamiento de enteros , y que sus consecuencias son la corrupción de la memoria (o, equivalentemente, violaciones de memoria y tipo de seguridad ). Todos estos son términos CS de propósito general definidos sin referencia a ningún lenguaje en particular o entorno del sistema operativo.

También es preciso observar que los efectos del error son similares a los efectos, dentro de un entorno moderno, de errores de corrupción de memoria que no provocan fallas de segmentación. Si lees cualquiera de los informes de exploits del Proyecto Cero , verás una notable similitud con el análisis de Don Hodges de la pantalla de asesinatos de Pac-Man .

Tenga en cuenta que un emulador que no reproduce fielmente la pantalla de eliminación cuando se alimenta con las ROM de Pac-Man no está emulando el hardware del juego correctamente.

zwol
fuente
Es posible que la frase "comportamiento indefinido" no se haya utilizado en forma impresa exactamente antes de 1989, pero la idea que describe esa frase es tan antigua como la programación misma. Common Lisp: The Language (Digital Press, 1984; ISBN 0-932376-41-X) utilizó las palabras "es un error" para significar exactamente lo mismo. Por ejemplo, "Es un error llamar a esta función con x <0" significa que el programador no debe permitir que se llame a la función con x <0 y que la implementación podía hacer literalmente cualquier cosa que el implementador quisiera que hiciera si el programador de la aplicación no cumplió.
Solomon Slow
55
@jameslarge Entiendo lo que quieres decir, pero sigo pensando que es un error aplicar este concepto a Pac-Man. Podemos decir que la pantalla de matar es un error porque el juego claramente no se comporta como el diseñador pretendía. No podemos decir que el juego haya provocado un comportamiento indefinido , porque no hay una especificación de lenguaje que diga "bajo ninguna circunstancia el programador puede hacer X" por ningún valor de X. (Supongo que el uso de los códigos de operación no documentados Z80 podría calificar, excepto que un montón de juegos de arcade hizo uso de esos y yo sepa que todos ellos tienen efectos predecibles).
Zwol
1
Esta es la mejor respuesta. "Comportamiento indefinido" significa que el codificador escribió un código para el que no se puede predecir el resultado según el estándar. Si Pacman está escrito en el ensamblaje Z80 (y creo que lo fue), entonces el código escrito tenía un significado completamente definido, independientemente de si el programa hizo algo que el codificador no pretendía.
Gort the Robot
8

El error de nivel 256 en Pac Man da como resultado que el programa lea los datos que están más allá del final de la tabla prevista, pero que aún se pueda leer , y que escriba en partes de la pantalla que estén más allá de las que el programa intenta escribir, pero son aún así dentro de las áreas de la pantalla que el programa está permitido escribir . No se ven afectadas otras áreas de la memoria.

La razón por la que el error hace que el juego no se pueda jugar es porque la máquina determina cuándo un jugador está comiendo puntos al examinar lo que está en la pantalla, y decide que un nivel está completo cuando el jugador ha comido 244 puntos. Al sobrescribir parte de la pantalla, el error hace que sea imposible para el jugador comer 244 puntos; en consecuencia, el juego nunca le dará crédito al jugador por completar el nivel y volverá a cargar la pantalla con puntos.

Super gato
fuente
1
Cuando te matas en el nivel 256, los puntos reaparecen, pero no pierdes ninguno.
Ave
@ardaozkal: la rutina de nivel de dibujo borra más de 100 puntos y dibuja algunos. Si un jugador tuviera suficientes vidas, eventualmente sería posible comer suficientes puntos para avanzar un nivel, pero eso requeriría más de 30 vidas.
supercat
Recuerdo haber visto un video en el que el jugador tenía suficientes vidas, y lo logró ... y lo encontré .
Ave
@ardaozkal: ¿Cuántas vidas se requieren para despejar el nivel y cuántas vidas puede obtener un jugador en una máquina sin modificar ?
supercat
Ni siquiera puede llegar al nivel 256 en una máquina sin modificar.
Ave
1

Como se dijo antes, no, no es una falla seg. Agregaré por qué ocurre el problema: es un desbordamiento .

Los números de nivel se almacenan en un byte, por lo que el rango es 0-255. Cada vez que completa un nivel, el contador se incrementa. En el nivel 256, el contador es de hecho 0 debido al desbordamiento.

Sin embargo, el juego intenta mostrar algunas frutas en la parte inferior del nivel. El número / tipo de fruta depende del nivel. La fórmula muestra una fruta por nivel final en el nivel 8. De acuerdo con el contador, usted está en el nivel 0, por lo tanto, en el nivel 8. La prueba es verdadera y debe imprimir 255 frutas (el valor del nivel anterior). Lo cual es imposible y le da a esta pantalla fallida.

Romain Picot
fuente