gdb: More cleanup changes

- Move the message handler into its debugger class part,
- Move all message types into one file and collapse 3 of the ones with no data into a generic, stateless message with a single property being its type,
- Add an Fpscr helper property on IExecutionContext along with a comment about what Fpscr is (similar to the other registers in there)
- Moved the Rcmd helpers (such as GetRegisters, GetMinidump, etc) into a dedicated Debugger class part,
- Fixed the double-collection (ToArray being called twice) in GetThreadUids & GetThread in KProcess
This commit is contained in:
GreemDev 2025-10-19 04:26:12 -05:00
parent 6058af5119
commit 247e2e03d6
19 changed files with 319 additions and 328 deletions

View file

@ -0,0 +1,103 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Kernel.Process;
using System;
using System.Text;
namespace Ryujinx.HLE.Debugger
{
public partial class Debugger
{
public string GetStackTrace()
{
if (GThread == null)
return "No thread selected\n";
return Process?.Debugger?.GetGuestStackTrace(DebugProcess.GetThread(GThread.Value)) ?? "No application process found\n";
}
public string GetRegisters()
{
if (GThread == null)
return "No thread selected\n";
return Process?.Debugger?.GetCpuRegisterPrintout(DebugProcess.GetThread(GThread.Value)) ?? "No application process found\n";
}
public string GetMinidump()
{
var response = new StringBuilder();
response.AppendLine("=== Begin Minidump ===\n");
response.AppendLine(GetProcessInfo());
foreach (var thread in GetThreads())
{
response.AppendLine($"=== Thread {thread.ThreadUid} ===");
try
{
string stackTrace = Process.Debugger.GetGuestStackTrace(thread);
response.AppendLine(stackTrace);
}
catch (Exception e)
{
response.AppendLine($"[Error getting stack trace: {e.Message}]");
}
try
{
string registers = Process.Debugger.GetCpuRegisterPrintout(thread);
response.AppendLine(registers);
}
catch (Exception e)
{
response.AppendLine($"[Error getting registers: {e.Message}]");
}
}
response.AppendLine("=== End Minidump ===");
Logger.Info?.Print(LogClass.GdbStub, response.ToString());
return response.ToString();
}
public string GetProcessInfo()
{
try
{
if (Process is not { } kProcess)
return "No application process found\n";
var sb = new StringBuilder();
sb.AppendLine($"Program Id: 0x{kProcess.TitleId:x16}");
sb.AppendLine($"Application: {(kProcess.IsApplication ? 1 : 0)}");
sb.AppendLine("Layout:");
sb.AppendLine(
$" Alias: 0x{kProcess.MemoryManager.AliasRegionStart:x10} - 0x{kProcess.MemoryManager.AliasRegionEnd - 1:x10}");
sb.AppendLine(
$" Heap: 0x{kProcess.MemoryManager.HeapRegionStart:x10} - 0x{kProcess.MemoryManager.HeapRegionEnd - 1:x10}");
sb.AppendLine(
$" Aslr: 0x{kProcess.MemoryManager.AslrRegionStart:x10} - 0x{kProcess.MemoryManager.AslrRegionEnd - 1:x10}");
sb.AppendLine(
$" Stack: 0x{kProcess.MemoryManager.StackRegionStart:x10} - 0x{kProcess.MemoryManager.StackRegionEnd - 1:x10}");
sb.AppendLine("Modules:");
var debugger = kProcess.Debugger;
if (debugger != null)
{
foreach (HleProcessDebugger.Image image in debugger.GetLoadedImages())
{
ulong endAddress = image.BaseAddress + image.Size - 1;
sb.AppendLine($" 0x{image.BaseAddress:x10} - 0x{endAddress:x10} {image.Name}");
}
}
return sb.ToString();
}
catch (Exception e)
{
Logger.Error?.Print(LogClass.GdbStub, $"Error getting process info: {e.Message}");
return $"Error getting process info: {e.Message}\n";
}
}
}
}