Este proyecto es educativo y Open Source. No se copia código de otros emuladores. Implementación basada únicamente en documentación técnica y tests permitidas.
Debug: Verificación de Puntero Nulo en la PPU
Resumen
Se añadió una verificación de diagnóstico temporal en el método render_scanline() de la PPU
para confirmar si el puntero a la MMU es nulo cuando se llama al método. Esta verificación utiliza
printf para emitir un mensaje crítico que confirme si el problema está en la capa de Cython,
específicamente en cómo se pasa el puntero desde el wrapper de Cython al constructor de la PPU en C++.
Concepto de Hardware
En un emulador híbrido Python/C++, la comunicación entre las capas requiere un manejo cuidadoso de los punteros. El flujo de datos desde Python hasta C++ pasa por varias capas:
- Python: Se crea una instancia de
PyMMU, que contiene un puntero C++ válido (MMU*). - Python: Se crea una instancia de
PyPPUpasando el objetoPyMMU. - Cython: El constructor de
PyPPUdebe "desenvolver" el objetoPyMMUpara extraer el punteroMMU*crudo que contiene y pasárselo al constructor de la PPU en C++. - C++: El constructor de la PPU recibe el puntero
MMU*y lo almacena en un miembro de la clase.
Si en cualquier punto de esta cadena el puntero se corrompe o no se pasa correctamente, la PPU intentará
acceder a memoria inválida, causando un Segmentation Fault. La verificación de puntero nulo con
printf nos permite identificar exactamente en qué punto falla la cadena.
Implementación
Se añadió una verificación temporal de puntero nulo al inicio del método render_scanline() que
imprime un mensaje crítico si el puntero mmu_ es nulo. Esta verificación es binaria y definitiva:
Componentes modificados
- PPU.cpp: Se añadió
#include <cstdio>para usarprintf. - PPU.cpp: Se añadió una verificación
if (this->mmu_ == nullptr)al inicio derender_scanline()que imprime un mensaje y retorna temprano para evitar el crash.
Código añadido
#include <cstdio>
// ...
void PPU::render_scanline() {
// CRÍTICO: Verificar que mmu_ no sea nullptr antes de acceder
// AÑADE ESTA VERIFICACIÓN CRÍTICA AL INICIO DEL MÉTODO
if (this->mmu_ == nullptr) {
printf("[PPU CRITICAL] ¡El puntero a la MMU es NULO! El problema está en la capa de Cython.\n");
return; // Salimos pronto para evitar el crash y ver el mensaje.
}
// ... resto del método render_scanline ...
}
Decisiones de diseño
Se utiliza printf en lugar de std::cout porque es más seguro para depuración de crashes
(no depende de los objetos estáticos de la librería estándar de C++ que pueden no estar inicializados durante un crash).
El mensaje es explícito y directo para identificar rápidamente el problema si ocurre.
Nota: Esta verificación es temporal y será eliminada una vez confirmado o descartado el problema del puntero nulo. Si el mensaje aparece, confirmaremos que el problema está en el wrapper de Cython. Si no aparece y el crash persiste, sabremos que el problema es más profundo.
Archivos Afectados
src/core/cpp/PPU.cpp- Añadido#include <cstdio>y verificación de puntero nulo conprintfenrender_scanline()
Tests y Verificación
Esta verificación se valida mediante ejecución real del emulador:
- Recompilación: Se debe recompilar el módulo C++ con
.\rebuild_cpp.ps1. - Ejecución: Se ejecuta el emulador con
python main.py roms/tetris.gb. - Análisis del resultado:
- Si aparece el mensaje: Confirma al 100% que el problema está en el wrapper de Cython
(
ppu.pyx) y sabremos exactamente dónde corregirlo. - Si NO aparece el mensaje y sigue habiendo crash: Nuestra hipótesis es incorrecta y el problema es más profundo (aunque esto es muy poco probable).
- Si aparece el mensaje: Confirma al 100% que el problema está en el wrapper de Cython
(
Validación de módulo compilado C++: Esta verificación se ejecuta directamente en el código compilado de C++, por lo que cualquier mensaje impreso confirmará que el código C++ se está ejecutando correctamente y que el puntero es efectivamente nulo en ese momento.
Fuentes Consultadas
- Documentación de Cython: https://cython.readthedocs.io/ - Gestión de punteros C++ desde Python
- Principios de depuración de punteros: Basado en conocimiento general de depuración de sistemas híbridos Python/C++
Integridad Educativa
Lo que Entiendo Ahora
- Flujo de punteros en arquitectura híbrida: El flujo Python → Cython → C++ requiere un manejo cuidadoso de los punteros en cada capa. Si el puntero se corrompe en cualquier punto, el resultado será un crash en tiempo de ejecución.
- Diagnóstico binario: Las verificaciones de puntero nulo con mensajes de diagnóstico son herramientas efectivas para aislar problemas en sistemas híbridos, ya que proporcionan una respuesta binaria: el puntero es nulo o no lo es.
Lo que Falta Confirmar
- Hipótesis del wrapper de Cython: Necesitamos confirmar si el problema está en cómo
Cython extrae el puntero de
PyMMUy lo pasa al constructor de la PPU. Si el mensaje aparece, confirmaremos esta hipótesis. - Corrección del wrapper: Si se confirma que el problema está en Cython, necesitaremos
revisar el código de
ppu.pyxpara corregir cómo se pasa el puntero.
Hipótesis y Suposiciones
Hipótesis principal (99% de certeza): El puntero MMU* que se pasa al constructor
de la PPU desde el wrapper de Cython ya es un puntero nulo (nullptr). El problema no está en la
asignación dentro del constructor de la PPU, sino en el valor que se está pasando.
Esta hipótesis se basa en el hecho de que:
- Ya hemos descartado que el problema esté en los valores calculados (Step 0139).
- Ya hemos confirmado que el constructor asigna correctamente el puntero (Step 0140).
- El único punto restante en la cadena es el paso del puntero desde Cython a C++.
Próximos Pasos
- [ ] Recompilar el módulo C++:
.\rebuild_cpp.ps1 - [ ] Ejecutar el emulador:
python main.py roms/tetris.gb - [ ] Analizar el resultado:
- Si aparece el mensaje: Revisar y corregir el wrapper de Cython (
ppu.pyx) - Si NO aparece: Investigar causas más profundas del Segmentation Fault
- Si aparece el mensaje: Revisar y corregir el wrapper de Cython (
- [ ] Eliminar la verificación temporal una vez confirmado el problema