This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Debug: Null Pointer Check on PPU
Summary
Added a temporary diagnostic check in the methodrender_scanline()of the PPU
to confirm whether the pointer to the MMU is null when the method is called. This verification usesprintfto issue a critical message confirming if the problem is at the Cython layer,
specifically in how the pointer is passed from the Cython wrapper to the PPU constructor in C++.
Hardware Concept
In a hybrid Python/C++ emulator, communication between layers requires careful handling of the pointers. The data flow from Python to C++ goes through several layers:
- Python:An instance is created
PyMMU, which contains a valid C++ pointer (MMU*). - Python:An instance is created
PyPPUpassing the objectPyMMU. - Cython:The builder of
PyPPUmust "unwrap" the objectPyMMUto extract the pointerMMU*raw file it contains and pass it to the PPU constructor in C++. - C++:The PPU constructor receives the pointer
MMU*and stores it in a member of the class.
If at any point in this chain the pointer becomes corrupted or is not passed correctly, the PPU will attempt to
accessing invalid memory, causing aSegmentation Fault. Checking for null pointer withprintfIt allows us to identify exactly where the chain fails.
Implementation
Added a temporary null pointer check to the start of the methodrender_scanline()that
prints a critical message if the pointermmu_is null. This verification is binary and definitive:
Modified components
- PPU.cpp:was added
#include <cstdio>to useprintf. - PPU.cpp:Added verification
if (this->mmu_ == nullptr)at the beginning ofrender_scanline()which prints a message and returns early to avoid the crash.
Code added
#include <cstdio>
//...
void PPU::render_scanline() {
// CRITICAL: Verify that mmu_ is not nullptr before accessing
// ADD THIS CRITICAL CHECK TO THE BEGINNING OF THE METHOD
if (this->mmu_ == nullptr) {
printf("[PPU CRITICAL] The pointer to the MMU is NULL! The problem is in the Cython layer.\n");
return; // We leave early to avoid the crash and see the message.
}
// ... rest of the render_scanline method ...
}
Design decisions
It is usedprintfratherstd::coutbecause it is safer for crash debugging
(it does not depend on static objects from the C++ standard library that may not be initialized during a crash).
The message is explicit and direct to quickly identify the problem if it occurs.
Note:This verification is temporary and will be removed once the problem is confirmed or ruled out. of the null pointer. If the message appears, we will confirm that the problem is in the Cython wrapper. If it does not appear and the crash persists, we will know that the problem is deeper.
Affected Files
src/core/cpp/PPU.cpp- Added#include <cstdio>and null pointer checking withprintfinrender_scanline()
Tests and Verification
This verification is validated by actual emulator execution:
- Recompilation:The C++ module must be recompiled with
.\rebuild_cpp.ps1. - Execution:Run the emulator with
python main.py roms/tetris.gb. - Analysis of the result:
- If the message appears:Confirm 100% that the problem is in the Cython wrapper
(
ppu.pyx) and we will know exactly where to correct it. - If the message does NOT appear and there is still a crash:Our hypothesis is incorrect and the problem is deeper (although this is highly unlikely).
- If the message appears:Confirm 100% that the problem is in the Cython wrapper
(
Compiled C++ module validation:This check is executed directly in the code compiled from C++, so any message printed will confirm that the C++ code is running correctly and that the pointer is effectively null at that moment.
Sources consulted
- Cython documentation:https://cython.readthedocs.io/- C++ pointer management from Python
- Principles of Pointer Debugging: Based on general knowledge of debugging Python/C++ hybrid systems
Educational Integrity
What I Understand Now
- Pointer flow in hybrid architecture:The Python → Cython → C++ flow requires careful handling of pointers at each layer. If the pointer becomes corrupted at any point, the result will be a crash at runtime.
- Binary diagnosis:Null pointer checks with diagnostic messages are effective tools for isolating problems in hybrid systems, as they provide a binary response: the pointer is null or it is not.
What remains to be confirmed
- Cython wrapper hypothesis:We need to confirm if the problem is how
Cython extracts the pointer from
PyMMUand passes it to the PPU constructor. If the message appears, we will confirm this hypothesis. - Wrapper fix:If the problem is confirmed to be in Cython, we will need
check the code
ppu.pyxto fix how the pointer is passed.
Hypotheses and Assumptions
Main hypothesis (99% certainty):The pointerMMU*which is passed to the constructor
of the PPU from the Cython wrapper is already a null pointer (nullptr). The problem is not in the
assignment within the PPU constructor, but in the value that is being passed.
This hypothesis is based on the fact that:
- We have already ruled out that the problem is in the calculated values (Step 0139).
- We have already confirmed that the constructor correctly assigns the pointer (Step 0140).
- The only remaining point in the chain is the pointer pass from Cython to C++.
Next Steps
- [ ] Recompile the C++ module:
.\rebuild_cpp.ps1 - [ ] Run the emulator:
python main.py roms/tetris.gb - [ ] Analyze the result:
- If the message appears: Review and correct the Cython wrapper (
ppu.pyx) - If it does NOT appear: Investigate deeper causes of the Segmentation Fault
- If the message appears: Review and correct the Cython wrapper (
- [ ] Remove the temporary check after the problem is confirmed