Fix GDB server crashes

This commit is contained in:
svc64 2023-11-11 17:08:25 +02:00
parent e3b8060417
commit 1684a9d7a2
2 changed files with 39 additions and 49 deletions

View file

@ -27,8 +27,7 @@ namespace Ryujinx.HLE.Debugger
private NetworkStream ReadStream = null; private NetworkStream ReadStream = null;
private NetworkStream WriteStream = null; private NetworkStream WriteStream = null;
private BlockingCollection<IMessage> Messages = new BlockingCollection<IMessage>(1); private BlockingCollection<IMessage> Messages = new BlockingCollection<IMessage>(1);
private Thread SocketThread; private Thread DebuggerThread;
private Thread HandlerThread;
private bool _shuttingDown = false; private bool _shuttingDown = false;
private ulong? cThread; private ulong? cThread;
@ -41,10 +40,8 @@ namespace Ryujinx.HLE.Debugger
ARMeilleure.Optimizations.EnableDebugging = true; ARMeilleure.Optimizations.EnableDebugging = true;
SocketThread = new Thread(SocketReaderThreadMain); DebuggerThread = new Thread(DebuggerThreadMain);
HandlerThread = new Thread(HandlerThreadMain); DebuggerThread.Start();
SocketThread.Start();
HandlerThread.Start();
} }
private IDebuggableProcess DebugProcess => Device.System.DebugGetApplicationProcess(); private IDebuggableProcess DebugProcess => Device.System.DebugGetApplicationProcess();
@ -144,21 +141,16 @@ namespace Ryujinx.HLE.Debugger
} }
} }
private void HandlerThreadMain() private void HandleMessage(IMessage msg)
{ {
while (true) switch (msg)
{ {
switch (Messages.Take()) case BreakInMessage:
{
case AbortMessage _:
return;
case BreakInMessage _:
Logger.Notice.Print(LogClass.GdbStub, "Break-in requested"); Logger.Notice.Print(LogClass.GdbStub, "Break-in requested");
CommandQuery(); CommandQuery();
break; break;
case SendNackMessage _: case SendNackMessage:
WriteStream.WriteByte((byte)'-'); WriteStream.WriteByte((byte)'-');
break; break;
@ -168,13 +160,12 @@ namespace Ryujinx.HLE.Debugger
ProcessCommand(cmd); ProcessCommand(cmd);
break; break;
case ThreadBreakMessage msg: case ThreadBreakMessage {Context: var ctx}:
DebugProcess.DebugStop(); DebugProcess.DebugStop();
Reply($"T05thread:{msg.Context.ThreadUid:x};"); Reply($"T05thread:{ctx.ThreadUid:x};");
break; break;
} }
} }
}
private void ProcessCommand(string cmd) private void ProcessCommand(string cmd)
{ {
@ -595,15 +586,23 @@ namespace Ryujinx.HLE.Debugger
Reply("E01"); Reply("E01");
} }
private void SocketReaderThreadMain() private void DebuggerThreadMain()
{ {
var endpoint = new IPEndPoint(IPAddress.Any, GdbStubPort); var endpoint = new IPEndPoint(IPAddress.Any, GdbStubPort);
ListenerSocket = new TcpListener(endpoint); ListenerSocket = new TcpListener(endpoint);
ListenerSocket.Start(); ListenerSocket.Start();
Logger.Notice.Print(LogClass.GdbStub, $"Currently waiting on {endpoint} for GDB client"); Logger.Notice.Print(LogClass.GdbStub, $"Currently waiting on {endpoint} for GDB client");
while (true) { while (!_shuttingDown)
{
try
{
ClientSocket = ListenerSocket.AcceptSocket(); ClientSocket = ListenerSocket.AcceptSocket();
}
catch (SocketException)
{
return;
}
ClientSocket.NoDelay = true; ClientSocket.NoDelay = true;
ReadStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Read); ReadStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Read);
WriteStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Write); WriteStream = new NetworkStream(ClientSocket, System.IO.FileAccess.Write);
@ -623,7 +622,7 @@ namespace Ryujinx.HLE.Debugger
Logger.Notice.Print(LogClass.GdbStub, "NACK received!"); Logger.Notice.Print(LogClass.GdbStub, "NACK received!");
continue; continue;
case '\x03': case '\x03':
Messages.Add(new BreakInMessage()); HandleMessage(new BreakInMessage());
break; break;
case '$': case '$':
string cmd = ""; string cmd = "";
@ -640,11 +639,11 @@ namespace Ryujinx.HLE.Debugger
string checksum = $"{(char)ReadStream.ReadByte()}{(char)ReadStream.ReadByte()}"; string checksum = $"{(char)ReadStream.ReadByte()}{(char)ReadStream.ReadByte()}";
if (checksum == $"{CalculateChecksum(cmd):x2}") if (checksum == $"{CalculateChecksum(cmd):x2}")
{ {
Messages.Add(new CommandMessage(cmd)); HandleMessage(new CommandMessage(cmd));
} }
else else
{ {
Messages.Add(new SendNackMessage()); HandleMessage(new SendNackMessage());
} }
break; break;
@ -659,8 +658,11 @@ namespace Ryujinx.HLE.Debugger
eof: eof:
Logger.Notice.Print(LogClass.GdbStub, "GDB client lost connection"); Logger.Notice.Print(LogClass.GdbStub, "GDB client lost connection");
ReadStream.Close(); ReadStream.Close();
ReadStream = null;
WriteStream.Close(); WriteStream.Close();
WriteStream = null;
ClientSocket.Close(); ClientSocket.Close();
ClientSocket = null;
} }
} }
@ -718,18 +720,12 @@ namespace Ryujinx.HLE.Debugger
{ {
_shuttingDown = true; _shuttingDown = true;
if (HandlerThread.IsAlive)
{
Messages.Add(new AbortMessage());
}
ListenerSocket.Stop(); ListenerSocket.Stop();
ClientSocket?.Shutdown(SocketShutdown.Both); ClientSocket?.Shutdown(SocketShutdown.Both);
ClientSocket?.Close(); ClientSocket?.Close();
ReadStream?.Close(); ReadStream?.Close();
WriteStream?.Close(); WriteStream?.Close();
SocketThread.Join(); DebuggerThread.Join();
HandlerThread.Join();
} }
} }

View file

@ -1,6 +0,0 @@
namespace Ryujinx.HLE.Debugger
{
struct AbortMessage : IMessage
{
}
}