mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-27 22:06:24 +02:00
gdb: Support continue specific threads
This commit is contained in:
parent
b932905053
commit
625ca3f934
3 changed files with 45 additions and 7 deletions
|
@ -411,13 +411,13 @@ namespace Ryujinx.HLE.Debugger
|
|||
break;
|
||||
}
|
||||
|
||||
if (DebugProcess.GetDebugState() == DebugState.Stopped)
|
||||
if (DebugProcess.IsThreadPaused(DebugProcess.GetThread(threadId.Value)))
|
||||
{
|
||||
Reply(ToHex("Stopped"));
|
||||
Reply(ToHex("Paused"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Reply(ToHex("Not stopped"));
|
||||
Reply(ToHex("Running"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -625,6 +625,8 @@ namespace Ryujinx.HLE.Debugger
|
|||
threadActionMap[thread.ThreadUid] = new VContPendingAction(VContAction.None);
|
||||
}
|
||||
|
||||
VContAction defaultAction = VContAction.None;
|
||||
|
||||
// For each inferior thread, the *leftmost* action with a matching thread-id is applied.
|
||||
for (int i = rawActions.Length - 1; i >= 0; i--)
|
||||
{
|
||||
|
@ -642,6 +644,7 @@ namespace Ryujinx.HLE.Debugger
|
|||
_ => VContAction.None
|
||||
};
|
||||
|
||||
// Note: We don't support signals yet.
|
||||
ushort? signal = null;
|
||||
if (cmd == 'C' || cmd == 'S')
|
||||
{
|
||||
|
@ -666,12 +669,17 @@ namespace Ryujinx.HLE.Debugger
|
|||
{
|
||||
threadActionMap[row.Key] = new VContPendingAction(action, signal);
|
||||
}
|
||||
|
||||
if (action == VContAction.Continue) {
|
||||
defaultAction = action;
|
||||
} else {
|
||||
Logger.Warning?.Print(LogClass.GdbStub, $"Received vCont command with unsupported default action: {rawAction}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
// TODO: We don't support stop or continue yet, and we don't support signals.
|
||||
foreach (var (threadUid, action) in threadActionMap)
|
||||
{
|
||||
if (action.Action == VContAction.Step)
|
||||
|
@ -683,10 +691,20 @@ namespace Ryujinx.HLE.Debugger
|
|||
}
|
||||
}
|
||||
|
||||
// If all threads are set to continue, continue the process.
|
||||
// If we receive "vCont;c", just continue the process.
|
||||
// If we receive something like "vCont;c:2e;c:2f" (IDA Pro will send commands like this), continue these threads.
|
||||
// For "vCont;s:2f;c", we only step thread 2f, and do not continue other threads. (Is this correct?)
|
||||
if (threadActionMap.Values.All(a => a.Action == VContAction.Continue))
|
||||
{
|
||||
DebugProcess.DebugContinue();
|
||||
} else if (defaultAction == VContAction.None) {
|
||||
foreach (var (threadUid, action) in threadActionMap)
|
||||
{
|
||||
if (action.Action == VContAction.Continue)
|
||||
{
|
||||
DebugProcess.DebugContinue(DebugProcess.GetThread(threadUid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasError)
|
||||
|
@ -716,7 +734,7 @@ namespace Ryujinx.HLE.Debugger
|
|||
foreach (var thread in GetThreads())
|
||||
{
|
||||
string threadName = System.Security.SecurityElement.Escape(thread.GetThreadName());
|
||||
sb.Append($"<thread id=\"{thread.ThreadUid:x}\" name=\"{threadName}\" />\n");
|
||||
sb.Append($"<thread id=\"{thread.ThreadUid:x}\" name=\"{threadName}\">{(DebugProcess.IsThreadPaused(thread) ? "Paused" : "Running")}</thread>\n");
|
||||
}
|
||||
|
||||
sb.Append("</threads>");
|
||||
|
|
|
@ -8,9 +8,11 @@ namespace Ryujinx.HLE.Debugger
|
|||
{
|
||||
void DebugStop();
|
||||
void DebugContinue();
|
||||
void DebugContinue(KThread thread);
|
||||
bool DebugStep(KThread thread);
|
||||
KThread GetThread(ulong threadUid);
|
||||
DebugState GetDebugState();
|
||||
bool IsThreadPaused(KThread thread);
|
||||
ulong[] GetThreadUids();
|
||||
public void DebugInterruptHandler(IExecutionContext ctx);
|
||||
IVirtualMemoryManager CpuMemory { get; }
|
||||
|
|
|
@ -1257,12 +1257,25 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
_kernelContext.CriticalSection.Leave();
|
||||
}
|
||||
|
||||
public void DebugContinue(KThread target)
|
||||
{
|
||||
Interlocked.Exchange(ref _parent.debugState, (int)DebugState.Running);
|
||||
|
||||
_kernelContext.CriticalSection.Enter();
|
||||
lock (_parent._threadingLock)
|
||||
{
|
||||
target.Resume(ThreadSchedState.ThreadPauseFlag);
|
||||
}
|
||||
_kernelContext.CriticalSection.Leave();
|
||||
}
|
||||
|
||||
public bool DebugStep(KThread target)
|
||||
{
|
||||
if (_parent.debugState != (int)DebugState.Stopped)
|
||||
if (!IsThreadPaused(target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_kernelContext.CriticalSection.Enter();
|
||||
steppingThread = target;
|
||||
bool waiting = target.MutexOwner != null || target.WaitingSync || target.WaitingInArbitration;
|
||||
|
@ -1322,6 +1335,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return (DebugState)_parent.debugState;
|
||||
}
|
||||
|
||||
public bool IsThreadPaused(KThread target)
|
||||
{
|
||||
return (target.SchedFlags & ThreadSchedState.ThreadPauseFlag) != 0;
|
||||
}
|
||||
|
||||
public ulong[] GetThreadUids()
|
||||
{
|
||||
lock (_parent._threadingLock)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue