Skip to main content

Overview

Effective debugging is essential for developing and troubleshooting Ryujinx. This guide covers debugging tools, techniques, and common issues developers encounter.
Make sure you’ve built Ryujinx in Debug configuration before following this guide.

Debug Build Configuration

Building for Debugging

# Build in Debug mode with symbols
dotnet build -c Debug

# Or publish with embedded debug symbols
dotnet publish -c Debug -p:DebugType=embedded

Debug vs Release

ConfigurationOptimizationsDebug SymbolsPerformanceUse Case
DebugDisabledFullSlowerDevelopment, debugging
ReleaseEnabledMinimalFastProduction, testing

IDE Debugging

Visual Studio (Windows)

1

Set startup project

Right-click Ryujinx project → Set as Startup Project
2

Set breakpoints

Click in the left margin next to line numbers to add breakpoints
3

Start debugging

Press F5 or select Debug → Start Debugging
4

Debug controls

  • F10: Step Over
  • F11: Step Into
  • Shift+F11: Step Out
  • F5: Continue
  • Shift+F5: Stop Debugging

Visual Studio Code

1

Install C# Dev Kit

2

Create launch configuration

Create .vscode/launch.json:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Ryujinx",
      "type": "coreclr",
      "request": "launch",
      "preLaunchTask": "build",
      "program": "${workspaceFolder}/src/Ryujinx/bin/Debug/net10.0/Ryujinx.dll",
      "args": [],
      "cwd": "${workspaceFolder}",
      "console": "internalConsole",
      "stopAtEntry": false
    }
  ]
}
3

Create build task

Create .vscode/tasks.json:
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "command": "dotnet",
      "type": "process",
      "args": [
        "build",
        "${workspaceFolder}/Ryujinx.sln",
        "-c",
        "Debug"
      ],
      "problemMatcher": "$msCompile"
    }
  ]
}
4

Start debugging

Press F5 or select Run → Start Debugging

JetBrains Rider

1

Open solution

Open Ryujinx.sln
2

Set run configuration

Select Ryujinx as the run configuration
3

Set breakpoints

Click in the gutter next to line numbers
4

Start debugging

Press Shift+F9 or click the debug icon

Common Debugging Scenarios

Debugging GPU Operations

GPU-related code is in src/Ryujinx.Graphics.Gpu/:
// Set breakpoint in shader compilation
// src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
public void ProcessShaderCacheQueue()
{
    while (_programsToSaveQueue.TryPeek(out ProgramToSave programToSave))
    {
        // Breakpoint here to inspect shader compilation
        ProgramLinkStatus result = programToSave.HostProgram.CheckProgramLink(false);
    }
}

Debugging CPU Emulation

CPU emulation code is in src/ARMeilleure/:
// Debug ARM instruction execution
// Set breakpoint in instruction decoder or execution
CPU emulation debugging can be extremely slow due to the high frequency of instruction execution.

Debugging HLE Services

High-level emulated services are in src/Ryujinx.HLE/:
// Debug service calls
// src/Ryujinx.HLE/HOS/Services/
// Set breakpoints in service implementations

Logging

Using Ryujinx Logger

Ryujinx uses a custom logging system from Ryujinx.Common.Logging:
using Ryujinx.Common.Logging;

// Different log levels
Logger.Debug?.Print(LogClass.Gpu, "Debug message");
Logger.Info?.Print(LogClass.Application, "Info message");
Logger.Warning?.Print(LogClass.Loader, "Warning message");
Logger.Error?.Print(LogClass.ServiceNv, "Error message");

Log Classes

Common log classes:
LogClassUsage
LogClass.ApplicationApplication-level messages
LogClass.GpuGPU-related operations
LogClass.LoaderGame/executable loading
LogClass.ServiceNvNVIDIA service emulation
LogClass.ServiceAmApplet manager service
LogClass.AudioAudio operations

Viewing Logs

Debug builds output logs to the console in real-time

Memory Debugging

Memory Management

Ryujinx has custom memory management in src/Ryujinx.Memory/:
// Debug memory allocations
using Ryujinx.Memory;

// Set breakpoints in MemoryManager methods
// to track memory operations

Detecting Memory Leaks

1

Use .NET memory profiling

Visual Studio and Rider have built-in memory profilers
2

Enable GC logging

set DOTNET_EnableEventLog=1
3

Use diagnostic tools

dotnet-counters monitor --process-id <PID>

Performance Profiling

See the dedicated Performance guide for detailed profiling techniques.

Quick Profiling

using System.Diagnostics;

var sw = Stopwatch.StartNew();
// Code to profile
sw.Stop();
Logger.Info?.Print(LogClass.Application, $"Operation took {sw.ElapsedMilliseconds}ms");

Conditional Compilation

Debug-Only Code

#if DEBUG
Logger.Debug?.Print(LogClass.Gpu, $"Shader compiled: {shaderProgram.Name}");
#endif

// Or use Debug class (removed in Release builds)
Debug.Assert(value != null, "Value should not be null");

Platform-Specific Debugging

#if WINDOWS
// Windows-specific debugging
#elif LINUX
// Linux-specific debugging
#elif OSX
// macOS-specific debugging
#endif

Crash Debugging

Stack Traces

When Ryujinx crashes, check:
  1. Console output for exception details
  2. Log files for the last operations
  3. Crash dumps if available

Exception Handling

try
{
    // Risky operation
}
catch (Exception ex)
{
    Logger.Error?.Print(LogClass.Application, $"Operation failed: {ex.Message}");
    Logger.Error?.Print(LogClass.Application, ex.StackTrace);
    throw; // Re-throw if fatal
}

Common Issues

Cause: Running Release build or optimizations enabledFix:
dotnet clean
dotnet build -c Debug
Cause: PDB files not generated or in wrong locationFix: Rebuild in Debug mode with full debug symbols:
dotnet build -c Debug -p:DebugType=full
Cause: Debug builds have all optimizations disabledFix: Use Release build for performance testing, Debug only when actively debugging
Cause: Variables optimized away in Release buildFix: Switch to Debug build or use [MethodImpl(MethodImplOptions.NoOptimization)]

Advanced Debugging

Debugging Tests

From src/Ryujinx.Tests/:
# Run specific test in debug mode
dotnet test --filter "FullyQualifiedName~ShaderCacheTests.TestShaderCompilation"
In IDE:
  1. Right-click on test method
  2. Select Debug Test

Attach to Running Process

  1. Debug → Attach to Process
  2. Select Ryujinx.exe or dotnet.exe
  3. Click Attach

Remote Debugging

For debugging on another machine or in Docker:
# Install remote debugger
dotnet tool install -g vsdbg

# Start with remote debugging enabled

Debugging Tools

.NET Diagnostic Tools

# Install tools
dotnet tool install -g dotnet-counters
dotnet tool install -g dotnet-trace
dotnet tool install -g dotnet-dump

# Monitor performance counters
dotnet-counters monitor --process-id <PID>

# Collect trace
dotnet-trace collect --process-id <PID>

# Analyze crash dump
dotnet-dump analyze <dump-file>

Third-Party Tools

Tips and Best Practices

Use conditional breakpoints

Right-click breakpoint → Conditions to break only when specific conditions are met

Use data breakpoints

Break when a specific variable’s value changes (VS/Rider)

Use tracepoints

Log messages without stopping execution (like adding Logger calls)

Check the Immediate Window

Execute code and inspect variables at runtime (VS)
Hot Reload is supported in .NET 10.0 - make code changes while debugging without restarting!

Next Steps

Testing

Write unit tests to prevent bugs

Performance

Profile and optimize code

Contributing

Submit your fixes

Build docs developers (and LLMs) love