Compare commits

...

4 commits

Author SHA1 Message Date
Coxxs
f511c4dd1c gdb: Update DebugPc during svc call 2025-06-21 05:28:12 +08:00
Coxxs
0d7abc0c4e gdb: Fix crash when gdb client disconnected in some cases 2025-06-21 05:27:39 +08:00
Coxxs
b6f6f8303f gdb: Add timeout to prevent deadlock in DebugStep
Deadlock can happen when step at some svc instructions.
2025-06-21 05:26:48 +08:00
Coxxs
4ffe38731b gdb: Fix GdbWriteRegister endianness 2025-06-21 05:25:22 +08:00
3 changed files with 64 additions and 38 deletions

View file

@ -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);
}

View file

@ -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;
@ -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);
}
}
}

View file

@ -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;
}