From 4ffe38731b10e352438c000bbc888a77b5482360 Mon Sep 17 00:00:00 2001 From: Coxxs <58-coxxs@users.noreply.git.ryujinx.app> Date: Sat, 21 Jun 2025 05:25:22 +0800 Subject: [PATCH 1/4] gdb: Fix GdbWriteRegister endianness --- src/Ryujinx.HLE/Debugger/Debugger.cs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Ryujinx.HLE/Debugger/Debugger.cs b/src/Ryujinx.HLE/Debugger/Debugger.cs index 3ec4dbb93..4350aab53 100644 --- a/src/Ryujinx.HLE/Debugger/Debugger.cs +++ b/src/Ryujinx.HLE/Debugger/Debugger.cs @@ -86,38 +86,38 @@ namespace Ryujinx.HLE.Debugger { case >= 0 and <= 31: { - ulong value = ss.ReadLengthAsHex(16); + ulong value = ss.ReadLengthAsLEHex(16); state.SetX(gdbRegId, value); return true; } case 32: { - ulong value = ss.ReadLengthAsHex(16); + ulong value = ss.ReadLengthAsLEHex(16); state.DebugPc = value; return true; } case 33: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.Pstate = (uint)value; return true; } case >= 34 and <= 65: { - ulong value0 = ss.ReadLengthAsHex(16); - ulong value1 = ss.ReadLengthAsHex(16); + ulong value0 = ss.ReadLengthAsLEHex(16); + ulong value1 = ss.ReadLengthAsLEHex(16); state.SetV(gdbRegId - 34, new V128(value0, value1)); return true; } case 66: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.Fpsr = (uint)value; return true; } case 67: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.Fpcr = (uint)value; return true; } @@ -158,32 +158,32 @@ namespace Ryujinx.HLE.Debugger { case >= 0 and <= 14: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.SetX(gdbRegId, value); return true; } case 15: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.DebugPc = value; return true; } case 16: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.Pstate = (uint)value; return true; } case >= 17 and <= 32: { - ulong value0 = ss.ReadLengthAsHex(16); - ulong value1 = ss.ReadLengthAsHex(16); + ulong value0 = ss.ReadLengthAsLEHex(16); + ulong value1 = ss.ReadLengthAsLEHex(16); state.SetV(gdbRegId - 17, new V128(value0, value1)); return true; } case >= 33 and <= 64: { - ulong value = ss.ReadLengthAsHex(16); + ulong value = ss.ReadLengthAsLEHex(16); int regId = (gdbRegId - 33); int regNum = regId / 2; int shift = regId % 2; @@ -193,7 +193,7 @@ namespace Ryujinx.HLE.Debugger } case 65: { - ulong value = ss.ReadLengthAsHex(8); + ulong value = ss.ReadLengthAsLEHex(8); state.Fpsr = (uint)value & FpcrMask; state.Fpcr = (uint)value & ~FpcrMask; return true; From b6f6f8303fedf84339ea77f4508fc4d4229819f4 Mon Sep 17 00:00:00 2001 From: Coxxs <58-coxxs@users.noreply.git.ryujinx.app> Date: Sat, 21 Jun 2025 05:26:48 +0800 Subject: [PATCH 2/4] gdb: Add timeout to prevent deadlock in DebugStep Deadlock can happen when step at some svc instructions. --- src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs index 7edf263e2..c24d5c3cc 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs @@ -1283,7 +1283,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } _kernelContext.CriticalSection.Leave(); - StepBarrier.SignalAndWait(); + bool stepTimedOut = false; + if (!StepBarrier.SignalAndWait(TimeSpan.FromMilliseconds(2000))) + { + Logger.Warning?.Print(LogClass.Kernel, $"Failed to step thread {target.ThreadUid} in time."); + stepTimedOut = true; + } _kernelContext.CriticalSection.Enter(); steppingThread = null; @@ -1302,6 +1307,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process target.Suspend(ThreadSchedState.ThreadPauseFlag); } _kernelContext.CriticalSection.Leave(); + + if (stepTimedOut) + { + return false; + } + StepBarrier.SignalAndWait(); return true; } From 0d7abc0c4edc9ec9204235e09abeb3516ab00490 Mon Sep 17 00:00:00 2001 From: Coxxs <58-coxxs@users.noreply.git.ryujinx.app> Date: Sat, 21 Jun 2025 05:27:39 +0800 Subject: [PATCH 3/4] gdb: Fix crash when gdb client disconnected in some cases --- src/Ryujinx.HLE/Debugger/Debugger.cs | 56 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/Ryujinx.HLE/Debugger/Debugger.cs b/src/Ryujinx.HLE/Debugger/Debugger.cs index 4350aab53..608ab977a 100644 --- a/src/Ryujinx.HLE/Debugger/Debugger.cs +++ b/src/Ryujinx.HLE/Debugger/Debugger.cs @@ -208,30 +208,40 @@ namespace Ryujinx.HLE.Debugger while (!_shuttingDown) { IMessage msg = Messages.Take(); - switch (msg) + try { + switch (msg) + { + case BreakInMessage: + Logger.Notice.Print(LogClass.GdbStub, "Break-in requested"); + CommandQuery(); + break; + + case SendNackMessage: + WriteStream.WriteByte((byte)'-'); + break; + + case CommandMessage { Command: var cmd }: + Logger.Debug?.Print(LogClass.GdbStub, $"Received Command: {cmd}"); + WriteStream.WriteByte((byte)'+'); + ProcessCommand(cmd); + break; + + case ThreadBreakMessage { Context: var ctx }: + DebugProcess.DebugStop(); + Reply($"T05thread:{ctx.ThreadUid:x};"); + break; + + case KillMessage: + return; + } + } + catch (IOException e) { - case BreakInMessage: - Logger.Notice.Print(LogClass.GdbStub, "Break-in requested"); - CommandQuery(); - break; - - case SendNackMessage: - WriteStream.WriteByte((byte)'-'); - break; - - case CommandMessage { Command: var cmd }: - Logger.Debug?.Print(LogClass.GdbStub, $"Received Command: {cmd}"); - WriteStream.WriteByte((byte)'+'); - ProcessCommand(cmd); - break; - - case ThreadBreakMessage { Context: var ctx }: - DebugProcess.DebugStop(); - Reply($"T05thread:{ctx.ThreadUid:x};"); - break; - - case KillMessage: - return; + Logger.Error?.Print(LogClass.GdbStub, "Error while processing GDB messages", e); + } + catch (NullReferenceException e) + { + Logger.Error?.Print(LogClass.GdbStub, "Error while processing GDB messages", e); } } } From f511c4dd1c021c8907cbb37ad855e8bbd0a2976e Mon Sep 17 00:00:00 2001 From: Coxxs <58-coxxs@users.noreply.git.ryujinx.app> Date: Sat, 21 Jun 2025 05:28:12 +0800 Subject: [PATCH 4/4] gdb: Update DebugPc during svc call --- src/ARMeilleure/State/ExecutionContext.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ARMeilleure/State/ExecutionContext.cs b/src/ARMeilleure/State/ExecutionContext.cs index 0b0a83c9f..5d8144d4e 100644 --- a/src/ARMeilleure/State/ExecutionContext.cs +++ b/src/ARMeilleure/State/ExecutionContext.cs @@ -169,6 +169,11 @@ namespace ARMeilleure.State internal void OnSupervisorCall(ulong address, int imm) { + if (Optimizations.EnableDebugging) + { + DebugPc = Pc; // TODO: Is this the best place to update DebugPc? + } + _supervisorCallback?.Invoke(this, address, imm); }