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?
Respuestas:
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 sí ocurrió.
fuente
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.
fuente
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.
fuente
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.
fuente
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.
fuente