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
Configuration Optimizations Debug Symbols Performance Use Case Debug Disabled Full Slower Development, debugging Release Enabled Minimal Fast Production, testing
IDE Debugging
Visual Studio (Windows)
Set startup project
Right-click Ryujinx project → Set as Startup Project
Set breakpoints
Click in the left margin next to line numbers to add breakpoints
Start debugging
Press F5 or select Debug → Start Debugging
Debug controls
F10 : Step Over
F11 : Step Into
Shift+F11 : Step Out
F5 : Continue
Shift+F5 : Stop Debugging
Visual Studio Code
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
}
]
}
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"
}
]
}
Start debugging
Press F5 or select Run → Start Debugging
JetBrains Rider
Open solution
Open Ryujinx.sln
Set run configuration
Select Ryujinx as the run configuration
Set breakpoints
Click in the gutter next to line numbers
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:
LogClass Usage 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
Logs are saved to:
Windows: %AppData%/Ryujinx/Logs/
Linux: ~/.config/Ryujinx/Logs/
macOS: ~/Library/Application Support/Ryujinx/Logs/
Named chronologically: Ryujinx_YYYYMMDD_HHmmss.log
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
Use .NET memory profiling
Visual Studio and Rider have built-in memory profilers
Enable GC logging
set DOTNET_EnableEventLog= 1
Use diagnostic tools
dotnet-counters monitor --process-id < PI D >
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" );
# if WINDOWS
// Windows-specific debugging
# elif LINUX
// Linux-specific debugging
# elif OSX
// macOS-specific debugging
# endif
Crash Debugging
Stack Traces
When Ryujinx crashes, check:
Console output for exception details
Log files for the last operations
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
Performance too slow in Debug
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:
Right-click on test method
Select Debug Test
Attach to Running Process
Visual Studio
VS Code
Command Line
Debug → Attach to Process
Select Ryujinx.exe or dotnet.exe
Click Attach
Add to launch.json: {
"name" : "Attach to Ryujinx" ,
"type" : "coreclr" ,
"request" : "attach" ,
"processId" : "${command:pickProcess}"
}
dotnet attach < process-i d >
Remote Debugging
For debugging on another machine or in Docker:
# Install remote debugger
dotnet tool install -g vsdbg
# Start with remote debugging enabled
# 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 < PI D >
# Collect trace
dotnet-trace collect --process-id < PI D >
# Analyze crash dump
dotnet-dump analyze < dump-fil e >
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