5.7 KiB
WASM Debugging Guide
This guide provides a comprehensive walkthrough for debugging and developing with the WASM version of YAZE. It covers common workflows such as loading ROMs, switching editors, and using the built-in debugging tools.
1. Getting Started
Running the WASM Server
To run the WASM version locally, use the provided script:
./scripts/serve-wasm.sh --dist build-wasm/dist --port 8080
This script ensures that the necessary Cross-Origin headers (COOP/COEP) are set, which are required for SharedArrayBuffer support.
Accessing the App
Open your browser (Chrome or Edge recommended) and navigate to:
http://localhost:8080
2. Loading a ROM
There are two ways to load a ROM file:
- File Input: Click the "Open ROM" folder icon in the top-left toolbar and select your
.sfcor.smcfile. - Drag and Drop: Drag a ROM file directly onto the application window.
Once loaded, the ROM info (name and size) will appear in the header status bar.
3. Switching Editors
YAZE provides multiple editors for different aspects of the ROM. You can switch between them using:
- Dropdown Menu: Click the "Editor" dropdown in the toolbar and select the desired editor (e.g., Dungeon, Overworld, Graphics).
- Command Palette: Press
Ctrl+K(orCmd+Kon Mac) and type "Editor" to filter the list. Select an editor and press Enter.
4. Editor Selection Dialog
Some editors, like the Dungeon Editor, may prompt you with a selection dialog when first opened (e.g., to select a dungeon room).
- Navigation: Use the mouse to click on a room or item in the list.
- Search: If available, use the search box to filter items.
- Confirm: Double-click an item or select it and click "OK".
5. Setting Layouts
You can customize the workspace layout using presets:
- Layout Menu: Click the "Layout" dropdown (grid icon) in the toolbar.
- Presets:
- Default: Standard layout for the current editor.
- Minimal: Maximizes the main view.
- All Cards: Shows all available tool cards.
- Debug: Opens additional debugging panels (Memory, Disassembly).
6. Debugging Tools
Emulator Controls
Control the emulation state via the "Emulator" dropdown or Command Palette:
- Run/Pause: Toggle execution.
- Step: Advance one frame.
- Reset: Soft reset the emulator.
Pixel Inspector
Debug palette and rendering issues:
- Click the "Pixel Inspector" icon (eyedropper) in the toolbar.
- Hover over the canvas to see pixel coordinates and palette indices.
- Click to log the current pixel's details to the browser console.
VSCode-Style Panels
Toggle the bottom panel using the terminal icon (~ or ` key) or the "Problems" icon (bug).
- Terminal: Execute WASM commands (type
/helpfor a list). - Problems: View errors and warnings, including palette validation issues.
- Output: General application logs.
Browser Console
Open the browser's developer tools (F12) to access the window.yazeDebug API for advanced debugging:
// Dump full application state
window.yazeDebug.dumpAll();
// Get graphics diagnostics
window.yazeDebug.graphics.getDiagnostics();
// Check memory usage
window.yazeDebug.memory.getUsage();
7. Debugging Memory Access Errors
Quick Methods to Find Out-of-Bounds Accesses
Method 1: Enable Emscripten SAFE_HEAP (Easiest)
Add -s SAFE_HEAP=1 to your Emscripten flags. This adds bounds checking to all memory accesses and will give you a precise error location.
In CMakePresets.json, add to CMAKE_CXX_FLAGS:
"CMAKE_CXX_FLAGS": "... -s SAFE_HEAP=1 -s ASSERTIONS=2"
Pros: Catches all out-of-bounds accesses automatically Cons: Slower execution (debugging only)
Method 2: Map WASM Function Number to Source
The error shows wasm-function[3704]. You can map this to source:
- Build with source maps: Add
-g4 -s SOURCE_MAP_BASE='http://localhost:8080/'to linker flags - Use
wasm-objdumpto list functions:wasm-objdump -x build-wasm/bin/yaze.wasm | grep -A 5 "func\[3704\]" - Or use browser DevTools: The stack trace should show function names if source maps are enabled
Method 3: Add Logging Wrapper
Create a ROM access wrapper that logs all accesses:
#ifdef __EMSCRIPTEN__
class DebugRomAccess {
public:
static bool CheckAccess(const uint8_t* data, size_t offset, size_t size,
size_t rom_size, const char* func_name) {
if (offset + size > rom_size) {
emscripten_log(EM_LOG_ERROR,
"OUT OF BOUNDS: %s accessing offset %zu + %zu (ROM size: %zu)",
func_name, offset, size, rom_size);
return false;
}
return true;
}
};
#endif
Common Pitfalls When Adding Bounds Checking
Pitfall 1: DecompressV2 Size Parameter
The DecompressV2 function has an early-exit when size == 0. Always pass 0x800 for the size parameter, not 0.
// CORRECT
DecompressV2(rom.data(), offset, 0x800, 1, rom.size())
// BROKEN - returns empty immediately
DecompressV2(rom.data(), offset, 0, 1, rom.size())
Pitfall 2: SMC Header Detection
The SMC header detection must use modulo 1MB, not 32KB:
// CORRECT
size % 1048576 == 512
// BROKEN - causes false positives
size % 0x8000 == 512
8. Common Issues & Solutions
- "SharedArrayBuffer is not defined": Ensure you are running the server with
serve-wasm.shto set the correct headers. - ROM not loading: Check the browser console for errors. Ensure the file is a valid SNES ROM.
- Canvas blank: Try resizing the window or toggling fullscreen to force a redraw.
- Out of bounds memory access: Enable SAFE_HEAP (see Section 7) to get precise error locations.