# How to Debug shadPS4-Emu Runtime Errors: A Complete Technical Guide

> Master shadPS4-Emu runtime errors with our technical guide. Learn to debug using gdb Visual Studio ImGui and synchronous logging for seamless emulation.

- Repository: [shadps4-emu/shadPS4](https://github.com/shadps4-emu/shadPS4)
- Tags: how-to-guide
- Published: 2026-03-19

---

**Enable synchronous logging in [`config.toml`](https://github.com/shadps4-emu/shadPS4/blob/main/config.toml), run shadPS4 under gdb or Visual Studio, and use the built-in ImGui devtools (Ctrl+F10) to capture frame dumps and inspect GPU state when runtime errors occur.**

shadPS4 is a PlayStation 4 emulator with a layered architecture separating the core emulation engine, Vulkan renderer, and ImGui-based developer UI. When debugging shadPS4-emu runtime errors, developers must correlate logs from [`src/common/logging/log.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/logging/log.h), assertions from [`src/common/assert.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/assert.h), and real-time GPU state from the devtools overlay.

## Understanding the Logging Infrastructure

shadPS4 uses a centralized logging system that supports both asynchronous (default) and synchronous modes. The logging macros, assertion handlers, and debug state singleton work together to provide a complete picture of runtime behavior.

### Core Logging Macros

The primary logging interface is defined in [`src/common/logging/log.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/logging/log.h). This file provides severity-based macros (`LOG_CRITICAL`, `LOG_ERROR`, `LOG_WARNING`, `LOG_INFO`, `LOG_DEBUG`) that automatically capture source file and line information.

```cpp
// Example: Logging a critical Vulkan error
LOG_CRITICAL(Render_Vulkan, "Failed to allocate image with error {}", vkResult);

```

Each macro expands to `LOG_GENERIC` with the appropriate `Class::` and `Level::` enum values, ensuring consistent formatting across the codebase.

### Assertion Handling

For fatal error conditions, [`src/common/assert.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/assert.h) provides `ASSERT` and `ASSERT_MSG` macros. When a condition fails, these call `assert_fail_impl()` and emit a `LOG_CRITICAL` message before aborting.

```cpp
#include "common/assert.h"

void InitGraphics() {
    bool ok = InitializeVulkanDevice();
    ASSERT_MSG(ok, "Vulkan device initialization failed");
}

```

### Debug State Singleton

The `DebugState` singleton in [`src/core/debug_state.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/debug_state.h) maintains per-frame debug data including frame counters, GPU dump requests, and message pop-ups. This class bridges the logging system and the ImGui devtools UI.

```cpp
// Request a frame dump from code (useful for automated tests)
DebugState.RequestFrameDump(1);  // Capture the next frame

```

### Configuration via config.toml

Logging behavior is controlled through `<executable>/user/config.toml`. Key settings include:

- `logType = "sync"` – Forces synchronous logging for deterministic output order
- `logFilter = "*:Debug"` – Sets verbosity level (e.g., `Render.Vulkan:Error` for specific subsystems)

The synchronous mode is essential when debugging race conditions or crashes that occur near the end of the log, as the default asynchronous mode may interleave messages from different threads.

## Using the ImGui Developer Tools

shadPS4 includes a comprehensive developer interface implemented in `src/core/devtools/` using ImGui. This overlay renders on top of the Vulkan output and provides real-time inspection capabilities.

### Accessing the Debug UI

Press **Ctrl+F10** (bound to "Video Debug Info" by default) to toggle the devtools overlay. The UI state is managed by the `DebugState` singleton and implemented in [`src/core/devtools/layer.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/devtools/layer.cpp).

You can also enable the UI programmatically:

```cpp
// Force enable devtools menu bar
DebugState.IsShowingDebugMenuBar() = true;

```

### GPU Tools and Frame Dumps

The **GPU Tools** menu provides critical debugging capabilities:

- **Dump frames** – Captures command buffers, register state, and shader binaries to `user/dumps/`
- **Frame Graph** – Visual timeline of GPU queues (DCB, CCB, ACB) and their submit numbers ([`src/core/devtools/widget/frame_graph.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/devtools/widget/frame_graph.cpp))
- **Pause in Submit** – Breaks execution at the next GPU command submission

Requesting a frame dump via the UI calls `DebugState.RequestFrameDump()`, which signals the renderer to capture the next frame's complete GPU state.

### Shader Debugging and Memory Inspection

For graphics-related runtime errors:

- **Shader List** ([`src/core/devtools/widget/shader_list.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/devtools/widget/shader_list.cpp)) – Lists compiled shaders; failed shaders appear with a red icon. Clicking a shader opens a disassembly view.
- **Memory Map** ([`src/core/devtools/widget/memory_map.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/devtools/widget/memory_map.h)) – Displays loaded modules, memory regions, and symbol information to detect corruption or invalid allocations.

## Step-by-Step Workflow to Debug Runtime Errors

Follow this systematic approach when investigating shadPS4 crashes or incorrect behavior:

1. **Enable deterministic logging** – Edit `<exe>/user/config.toml`:
   ```toml
   logType = "sync"
   logFilter = "*:Debug"
   ```

2. **Run under a native debugger**:
   - **Linux/macOS**: `gdb --args ./shadps4 <game_path>`
   - **Windows**: Open in Visual Studio with **x64-Clang-Debug** configuration and press **F5**

3. **Reproduce the crash** – The debugger breaks on unhandled exceptions. For `ASSERT` failures, execution stops at `assert_fail_impl()` with the call stack pointing to the source (e.g., `src/video_core/renderer_vulkan/vk_swapchain.cpp:121`).

4. **Inspect the log** – Check the console or [`user/log/shad_log.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/user/log/shad_log.txt). The most recent `LOG_CRITICAL` or `LOG_ERROR` entry explains the failure. Filter noise by adjusting `logFilter` (e.g., `Render.Vulkan:Error`).

5. **Use the devtools UI** – Press **Ctrl+F10** and navigate to:
   - **GPU Tools → Dump frames** (`Ctrl+Alt+F9`) to capture GPU state
   - **Shader List** to verify failed shader compilation
   - **Memory Map** to check for corrupted allocations

6. **Optional: Enable RenderDoc** – Set `rdocEnable = true` in [`config.toml`](https://github.com/shadps4-emu/shadPS4/blob/main/config.toml). The emulator launches RenderDoc automatically on the next frame for detailed Vulkan command inspection.

7. **Analyze the stack trace** – Focus on calls originating in `src/core/` or `src/video_core/` rather than game code. These indicate emulator bugs requiring patches.

8. **Apply a fix** – Common solutions include:
   - **Vulkan resource states** – Check `vk::Result` handling in `src/video_core/renderer_vulkan/*.cpp`
   - **Shader compilation** – Verify `CollectShader` in [`vk_pipeline_cache.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/vk_pipeline_cache.cpp)
   - **Memory mapping** – Check `Memory::Allocate` in [`src/core/memory.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/memory.cpp)

9. **Re-run the test** – Repeat steps 1-7. Resolution is confirmed when the emulator runs without crashes and logs contain no `CRITICAL` entries.

## Configuration Knobs for Advanced Debugging

Fine-tune shadPS4's behavior using these [`config.toml`](https://github.com/shadps4-emu/shadPS4/blob/main/config.toml) settings documented in [`src/documents/Debugging/Debugging.md`](https://github.com/shadps4-emu/shadPS4/blob/main/src/documents/Debugging/Debugging.md):

| Setting | Value | Effect |
|---------|-------|--------|
| `logType` | `"sync"` | Forces synchronous logging for deterministic output order |
| `logFilter` | `"*:Debug"` or `"Render.Vulkan:Error"` | Controls verbosity per subsystem |
| `rdocEnable` | `true` | Auto-launches RenderDoc for Vulkan debugging |
| `vkValidation` | `true` | Enables Vulkan validation layers for detailed error messages |
| `shouldDumpShaders` | `true` | Writes SPIR-V binaries to `user/shader/dumps` |

These settings can also be adjusted at runtime via **GPU Tools → Options** in the devtools UI.

## Platform-Specific Debugger Setup

### Linux and macOS (gdb/LLDB)

Attach to shadPS4 using standard Unix debuggers:

```bash

# GDB

gdb --args ./shadps4 /path/to/game/eboot.bin

# LLDB (macOS)

lldb -- ./shadps4 /path/to/game/eboot.bin

```

Set breakpoints on critical functions:

```gdb
break assert_fail_impl
break vk::Device::createImage

```

### Windows (Visual Studio)

1. Open `shadPS4.sln` in Visual Studio 2022
2. Set configuration to **x64-Clang-Debug** (or **x64-Debug**)
3. Set startup project to `shadps4`
4. Press **F5** to launch with debugging

Configure exception handling to ignore intentional guard exceptions used by the emulator's memory management (as noted in the Debugging guide).

## Summary

- **Enable synchronous logging** via `logType = "sync"` in [`config.toml`](https://github.com/shadps4-emu/shadPS4/blob/main/config.toml) to ensure ordered log output during crashes.
- **Run under gdb, LLDB, or Visual Studio** to catch assertions and exceptions at `assert_fail_impl()` and inspect call stacks.
- **Use the ImGui devtools** (Ctrl+F10) to access GPU frame dumps, shader lists, and memory maps in real-time.
- **Configure advanced options** like `rdocEnable` and `vkValidation` for Vulkan-specific debugging with RenderDoc and validation layers.
- **Focus on emulator code** in `src/core/` and `src/video_core/` when analyzing stack traces to identify bugs requiring patches.

## Frequently Asked Questions

### How do I enable synchronous logging in shadPS4?

Edit the [`config.toml`](https://github.com/shadps4-emu/shadPS4/blob/main/config.toml) file located in `<executable>/user/config.toml` and set `logType = "sync"`. This forces the logging system defined in [`src/common/logging/log.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/logging/log.h) to write messages immediately rather than buffering them asynchronously, ensuring that log output appears in the correct chronological order when debugging race conditions or crashes.

### What is the keyboard shortcut to open the devtools UI?

Press **Ctrl+F10** to toggle the ImGui-based developer overlay implemented in [`src/core/devtools/layer.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/devtools/layer.cpp). This shortcut, bound to "Video Debug Info" by default, opens the debug menu bar where you can access GPU Tools, Shader Lists, Memory Maps, and Frame Graphs without restarting the emulator.

### How can I capture a GPU frame dump when a runtime error occurs?

Open the devtools UI (Ctrl+F10), navigate to **GPU Tools**, and select **Dump frames** (or press Ctrl+Alt+F9). This triggers `DebugState.RequestFrameDump()` defined in [`src/core/debug_state.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/debug_state.h), which captures the next frame's command buffers, register state, and shader binaries to `user/dumps/`. You can also call `DebugState.RequestFrameDump(1)` programmatically from C++ code.

### Which debugger should I use for shadPS4 on Windows?

Use **Visual Studio 2022** with the **x64-Clang-Debug** or **x64-Debug** configuration. Set the `shadps4` project as the startup project and press F5 to launch. Visual Studio integrates seamlessly with the emulator's assertion handling in [`src/common/assert.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/assert.h) and allows you to inspect Vulkan resource states in `src/video_core/renderer_vulkan/` when runtime errors trigger `assert_fail_impl()`.