Files
yaze/docs/internal/wasm/debugging.md

168 lines
5.7 KiB
Markdown

# 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:
```bash
./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:
1. **File Input**: Click the "Open ROM" folder icon in the top-left toolbar and select your `.sfc` or `.smc` file.
2. **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` (or `Cmd+K` on 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:
1. Click the "Pixel Inspector" icon (eyedropper) in the toolbar.
2. Hover over the canvas to see pixel coordinates and palette indices.
3. 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 `/help` for 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:
```javascript
// 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`:
```json
"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:
1. Build with source maps: Add `-g4 -s SOURCE_MAP_BASE='http://localhost:8080/'` to linker flags
2. Use `wasm-objdump` to list functions:
```bash
wasm-objdump -x build-wasm/bin/yaze.wasm | grep -A 5 "func\[3704\]"
```
3. 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:
```cpp
#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`.
```cpp
// 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:
```cpp
// 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.sh` to 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.