1 puntos por GN⁺ 2025-04-24 | 1 comentarios | Compartir por WhatsApp
  • Un bug de 20 años en GTA San Andreas sale a la luz en Windows 11 24H2
    • Se reportó un bug en GTA San Andreas donde el avión Skimmer desaparece en Windows 11 24H2
    • El problema no se resuelve ni siquiera usando SilentPatch
    • En Windows 11 23H2 el problema no ocurre
    • Todos los usuarios que actualizaron a Windows 11 24H2 experimentan este bug

Investigación del bug

¿Qué salió mal?

  • Al instalar SilentPatch, el juego se congela
  • Se descubrió que queda atrapado en un pequeño bucle dentro de CPlane::PreRender
  • La velocidad de las hélices del avión está configurada de forma anormalmente alta
  • La velocidad de las hélices se calcula en proporción a la altitud del avión

¿Por qué y cómo?

  • Falta un parámetro necesario en la definición de Skimmer dentro de vehicles.ide
  • En Vice City, Skimmer estaba definido como un bote
  • En San Andreas se cambió a avión, pero no se agregó el parámetro necesario

La verdadera causa raíz

  • El problema ocurre porque en Windows 11 24H2 cambió la forma en que se usa la pila
  • LeaveCriticalSection ahora pasa a usar más espacio de pila
  • Antes, fgets y LeaveCriticalSection no sobrescribían ese espacio de pila, pero ahora sí

Por qué este problema aparece recién ahora

  • Los cambios en Windows 11 24H2 alteraron el espacio de pila
  • El juego provocaba este problema al usar una variable local sin inicializar
  • En otras plataformas este problema ya había sido corregido

¿Quieres arreglar este problema en el juego?

  • La próxima corrección urgente de SilentPatch incluirá un arreglo en el código
  • También es posible resolver el problema editando manualmente el archivo vehicles.ide

Comentario final

  • Este bug es interesante porque está directamente ligado a una versión específica del sistema operativo
  • Muestra que los cambios en el layout de la pila pueden afectar la compatibilidad
  • Hay que validar los datos de entrada y no ignorar las advertencias del compilador

1 comentarios

 
GN⁺ 2025-04-24
Opiniones de Hacker News
  • Es el tipo de trabajo que uno esperaría de Raymond Chen. Eso es un elogio enorme
  • Me alegra que hayan rastreado la causa del problema con más profundidad
  • En mi opinión, lo que no forme parte del contrato debería manejarse de forma aleatoria. Por ejemplo, si un lenguaje no garantiza el orden de iteración de un mapa, entonces el lenguaje debería aleatorizarlo. De lo contrario, el código se vuelve frágil
  • No se deberían ignorar las advertencias del compilador. Es probable que este código haya generado advertencias en el código original
  • ¿Qué error del compilador cabría esperar aquí? Probablemente que no se verifica el valor de retorno de scanf para comprobar que coincide con la cantidad de parámetros. Fuera de eso, parece un error en un archivo de datos que el compilador no puede conocer
  • Siempre disfruto leer artículos técnicos. Me pregunto qué tan raros se volverán en la era de la IA
  • Me pregunto qué cambió en la implementación de bloqueo/desbloqueo de secciones críticas de Windows
  • Gracias por proporcionar un enlace para las personas que tienen problemas de acceso
  • Leer y escribir más allá de la pila siempre ha sido demasiado fácil. Esto simplemente debería fallar
  • Sí existen mitigaciones: ASLR, páginas NX, protección contra stack smashing, etc. Pero no evitan por completo leer datos antiguos más allá de la pila
  • Un experimento mental: ¿qué pasaría si el hardware no permitiera leer ni escribir en las partes no usadas del área de la pila?
  • Propuesta de una forma de rastrear la dirección inicial A de la pila, su tamaño S y la profundidad actual D
    • Agregar una instrucción para indicarle a la CPU que la pila existe en la dirección A con tamaño S
    • Agregar una instrucción de salto que reserve N bytes en la pila
    • Agregar conciencia de la pila a la instrucción de retorno existente
    • Hacer que cualquier lectura o escritura en el área de la pila más allá de la profundidad actual falle
    • En arquitecturas donde la pila crece hacia abajo, la aritmética se aplicaría al revés
  • Como desventajas, fija una sola convención de llamada y el administrador de memoria de la CPU necesitaría mucho estado
  • La pila está en todas partes. Que el hardware sea consciente de la pila abriría nuevas mitigaciones
  • ¿Por qué esta idea no es común? ¿Se ha intentado antes?
  • Todo esto demuestra que no es un problema de Windows 11 24H2. El juego depende de comportamiento indefinido
  • El comportamiento indefinido es muy traicionero: hace que creas que tienes razón aunque ya cometiste un error
  • Si un programa en C o C++ provoca comportamiento indefinido, cualquier cosa puede pasar durante su ejecución
  • Si tienes suerte, el programa mostrará un mensaje de error adecuado o fallará, y te darás cuenta de inmediato de que hay un problema
  • Si tienes mala suerte, el programa corromperá datos en silencio y, para cuando notes el problema, la causa ya quedó enterrada en el historial de ejecuciones pasadas
  • Si tienes muy mala suerte, el programa funcionará como quieres hasta que cambies código no relacionado, o cambies la versión del compilador, el sistema operativo, etc., y aparezcan nuevos bugs
  • Sugerencias para encontrar una mejor forma de trabajar como desarrollador
    • Leer, entender y memorizar el comportamiento indefinido en C o C++, y evitarlo
    • Compilar la aplicación en modo debug y compararla con el modo release; si hay diferencias, hay un problema serio
    • Usar herramientas como -fsanitize=undefined,address para detectar comportamiento indefinido en tiempo de ejecución
    • Se recomienda usar lenguajes administrados como Java, C#, Python. O usar un lenguaje seguro de bajo nivel como Rust
  • Recomendación de usar un depurador. He escuchado historias sobre los problemas de no usar uno
  • Mucho cariño para Silent. Lleva más de 10 años mejorando juegos que me gustan