mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 17:39:28 +00:00
thermosphere: gdb: properly handle vStopped ack sequence
This commit is contained in:
parent
36ca87491d
commit
b0ca29d18e
3 changed files with 33 additions and 12 deletions
|
@ -130,9 +130,14 @@ static void GDB_Disconnect(GDBContext *ctx)
|
||||||
ctx->currentThreadId = 0;
|
ctx->currentThreadId = 0;
|
||||||
ctx->selectedThreadId = 0;
|
ctx->selectedThreadId = 0;
|
||||||
ctx->selectedThreadIdForContinuing = 0;
|
ctx->selectedThreadIdForContinuing = 0;
|
||||||
|
ctx->sentDebugEventCoreList = 0;
|
||||||
|
ctx->acknowledgedDebugEventCoreList = 0;
|
||||||
|
|
||||||
|
ctx->attachedCoreList = 0;
|
||||||
|
ctx->sendOwnDebugEventDisallowed = false;
|
||||||
ctx->catchThreadEvents = false;
|
ctx->catchThreadEvents = false;
|
||||||
ctx->lastSentPacketSize = 0;
|
ctx->lastSentPacketSize = 0;
|
||||||
|
ctx->lastDebugEvent = NULL;
|
||||||
|
|
||||||
ctx->processEnded = false;
|
ctx->processEnded = false;
|
||||||
ctx->processExited = false;
|
ctx->processExited = false;
|
||||||
|
|
|
@ -78,8 +78,9 @@ typedef struct GDBContext {
|
||||||
int selectedThreadIdForContinuing;
|
int selectedThreadIdForContinuing;
|
||||||
|
|
||||||
u32 sentDebugEventCoreList;
|
u32 sentDebugEventCoreList;
|
||||||
|
u32 acknowledgedDebugEventCoreList;
|
||||||
|
|
||||||
bool sendOwnDebugEventAllowed;
|
bool sendOwnDebugEventDisallowed;
|
||||||
|
|
||||||
bool catchThreadEvents;
|
bool catchThreadEvents;
|
||||||
bool processEnded, processExited;
|
bool processEnded, processExited;
|
||||||
|
|
|
@ -177,6 +177,9 @@ int GDB_SendStopReply(GDBContext *ctx, const DebugEventInfo *info, bool asNotifi
|
||||||
} else if (asNotification) {
|
} else if (asNotification) {
|
||||||
return GDB_SendNotificationPacket(ctx, buf, strlen(buf));
|
return GDB_SendNotificationPacket(ctx, buf, strlen(buf));
|
||||||
} else {
|
} else {
|
||||||
|
if (!(ctx->flags & GDB_FLAG_NONSTOP)) {
|
||||||
|
ctx->acknowledgedDebugEventCoreList |= BIT(info->coreId);
|
||||||
|
}
|
||||||
return GDB_SendPacket(ctx, buf, strlen(buf));
|
return GDB_SendPacket(ctx, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,14 +213,14 @@ int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info)
|
||||||
if (!GDB_IsAttached(ctx)) {
|
if (!GDB_IsAttached(ctx)) {
|
||||||
// Not attached, mark the event as handled, unpause
|
// Not attached, mark the event as handled, unpause
|
||||||
debugManagerMarkAndGetCoreDebugEvent(info->coreId);
|
debugManagerMarkAndGetCoreDebugEvent(info->coreId);
|
||||||
debugManagerUnpauseCores(BIT(info->coreId), 0);
|
debugManagerUnpauseCores(BIT(info->coreId));
|
||||||
GDB_ReleaseContext(ctx);
|
GDB_ReleaseContext(ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we still paused & has the packet not been handled & are we allowed to send on our own?
|
// Are we still paused & has the packet not been handled & are we allowed to send on our own?
|
||||||
|
|
||||||
if (ctx->sendOwnDebugEventAllowed && !info->handled && debugManagerIsCorePaused(info->coreId)) {
|
if (!ctx->sendOwnDebugEventDisallowed && !info->handled && debugManagerIsCorePaused(info->coreId)) {
|
||||||
bool nonStop = (ctx->flags & GDB_FLAG_NONSTOP) != 0;
|
bool nonStop = (ctx->flags & GDB_FLAG_NONSTOP) != 0;
|
||||||
info->handled = true;
|
info->handled = true;
|
||||||
|
|
||||||
|
@ -226,7 +229,7 @@ int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info)
|
||||||
debugManagerPauseCores(ctx->attachedCoreList & ~BIT(info->coreId));
|
debugManagerPauseCores(ctx->attachedCoreList & ~BIT(info->coreId));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->sendOwnDebugEventAllowed = false;
|
ctx->sendOwnDebugEventDisallowed = true;
|
||||||
ret = GDB_SendStopReply(ctx, info, nonStop);
|
ret = GDB_SendStopReply(ctx, info, nonStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,16 +252,21 @@ GDB_DECLARE_VERBOSE_HANDLER(Stopped)
|
||||||
u32 coreList = debugManagerGetPausedCoreList() & ctx->attachedCoreList;
|
u32 coreList = debugManagerGetPausedCoreList() & ctx->attachedCoreList;
|
||||||
u32 remaining = coreList & ~ctx->sentDebugEventCoreList;
|
u32 remaining = coreList & ~ctx->sentDebugEventCoreList;
|
||||||
|
|
||||||
|
// Ack
|
||||||
|
if (ctx->lastDebugEvent != NULL) {
|
||||||
|
ctx->acknowledgedDebugEventCoreList |= BIT(ctx->lastDebugEvent->coreId);
|
||||||
|
}
|
||||||
|
|
||||||
if (remaining != 0) {
|
if (remaining != 0) {
|
||||||
// Send one more debug event (marking it as handled)
|
// Send one more debug event (marking it as handled)
|
||||||
u32 coreId = __builtin_ctz(remaining);
|
u32 coreId = __builtin_ctz(remaining);
|
||||||
DebugEventInfo *info = debugManagerMarkAndGetCoreDebugEvent(coreId);
|
DebugEventInfo *info = debugManagerMarkAndGetCoreDebugEvent(coreId);
|
||||||
|
|
||||||
ctx->sendOwnDebugEventAllowed = false;
|
ctx->sendOwnDebugEventDisallowed = true;
|
||||||
return GDB_SendStopReply(ctx, info, false);
|
return GDB_SendStopReply(ctx, info, false);
|
||||||
} else {
|
} else {
|
||||||
// vStopped sequenced finished
|
// vStopped sequenced finished
|
||||||
ctx->sendOwnDebugEventAllowed = true;
|
ctx->sendOwnDebugEventDisallowed = false;
|
||||||
return GDB_ReplyOk(ctx);
|
return GDB_ReplyOk(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +280,9 @@ GDB_DECLARE_HANDLER(GetStopReason)
|
||||||
} else {
|
} else {
|
||||||
// Non-stop, start new vStopped sequence
|
// Non-stop, start new vStopped sequence
|
||||||
ctx->sentDebugEventCoreList = 0;
|
ctx->sentDebugEventCoreList = 0;
|
||||||
ctx->sendOwnDebugEventAllowed = false;
|
ctx->acknowledgedDebugEventCoreList = 0;
|
||||||
|
ctx->lastDebugEvent = NULL;
|
||||||
|
ctx->sendOwnDebugEventDisallowed = true;
|
||||||
return GDB_HandleVerboseStopped(ctx);
|
return GDB_HandleVerboseStopped(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,8 +357,9 @@ GDB_DECLARE_HANDLER(ContinueOrStepDeprecated)
|
||||||
debugManagerSetSteppingRange(coreId, 0, 0);
|
debugManagerSetSteppingRange(coreId, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugManagerSetSingleStepCoreList(ssMask);
|
u32 mask = ctx->acknowledgedDebugEventCoreList;
|
||||||
debugManagerUnpauseCores(coreList);
|
debugManagerSetSingleStepCoreList(ssMask & mask);
|
||||||
|
debugManagerUnpauseCores(coreList & mask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,9 +473,13 @@ GDB_DECLARE_VERBOSE_HANDLER(Continue)
|
||||||
cmd = nextCmd;
|
cmd = nextCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugManagerSetSingleStepCoreList(stepCoreList);
|
// "Note: In non-stop mode, a thread is considered running until GDB acknowledges
|
||||||
debugManagerBreakCores(stopCoreList);
|
// an asynchronous stop notification for it with the ‘vStopped’ packet (see Remote Non-Stop)."
|
||||||
debugManagerContinueCores(continueCoreList);
|
u32 mask = ctx->acknowledgedDebugEventCoreList;
|
||||||
|
|
||||||
|
debugManagerSetSingleStepCoreList(stepCoreList & mask);
|
||||||
|
debugManagerBreakCores(stopCoreList & ~mask);
|
||||||
|
debugManagerContinueCores(continueCoreList & mask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue