gdb: fix multiple extended-remote issues, also fix possible race condtions
This commit is contained in:
parent
54de645dc3
commit
17ca09346d
@ -37,6 +37,7 @@ typedef struct GDBServer
|
||||
sock_server super;
|
||||
s32 referenceCount;
|
||||
Handle statusUpdated;
|
||||
Handle statusUpdateReceived;
|
||||
GDBContext ctxs[MAX_DEBUG];
|
||||
} GDBServer;
|
||||
|
||||
|
@ -175,7 +175,9 @@ void GDB_DetachFromProcess(GDBContext *ctx)
|
||||
ctx->eventToWaitFor = ctx->processAttachedEvent;
|
||||
ctx->continueFlags = (DebugFlags)(DBG_SIGNAL_FAULT_EXCEPTION_EVENTS | DBG_INHIBIT_USER_CPU_EXCEPTION_HANDLERS);
|
||||
ctx->pid = 0;
|
||||
ctx->currentThreadId = ctx->selectedThreadId = ctx->selectedThreadIdForContinuing = 0;
|
||||
ctx->currentThreadId = 0;
|
||||
ctx->selectedThreadId = 0;
|
||||
ctx->selectedThreadIdForContinuing = 0;
|
||||
ctx->nbThreads = 0;
|
||||
ctx->totalNbCreatedThreads = 0;
|
||||
memset(ctx->threadInfos, 0, sizeof(ctx->threadInfos));
|
||||
|
@ -43,9 +43,15 @@ static void GDB_DetachImmediatelyExtended(GDBContext *ctx)
|
||||
{
|
||||
// detach immediately
|
||||
RecursiveLock_Lock(&ctx->lock);
|
||||
svcSignalEvent(ctx->parent->statusUpdated); // note: monitor will be waiting for lock
|
||||
|
||||
ctx->state = GDB_STATE_DETACHING;
|
||||
|
||||
svcClearEvent(ctx->parent->statusUpdateReceived);
|
||||
svcSignalEvent(ctx->parent->statusUpdated);
|
||||
RecursiveLock_Unlock(&ctx->lock);
|
||||
|
||||
svcWaitSynchronization(ctx->parent->statusUpdateReceived, -1LL);
|
||||
|
||||
RecursiveLock_Lock(&ctx->lock);
|
||||
GDB_DetachFromProcess(ctx);
|
||||
ctx->flags &= GDB_FLAG_PROC_RESTART_MASK;
|
||||
RecursiveLock_Unlock(&ctx->lock);
|
||||
@ -279,7 +285,15 @@ GDB_DECLARE_VERBOSE_HANDLER(Continue)
|
||||
|
||||
GDB_DECLARE_HANDLER(GetStopReason)
|
||||
{
|
||||
return ctx->debug != 0 ? GDB_SendStopReply(ctx, &ctx->latestDebugEvent) : GDB_SendPacket(ctx, "W00", 3); // "process exited" if nothing
|
||||
if (ctx->processEnded && ctx->processExited) {
|
||||
return GDB_SendPacket(ctx, "W00", 3);
|
||||
} else if (ctx->processEnded && !ctx->processExited) {
|
||||
return GDB_SendPacket(ctx, "X0f", 3);
|
||||
} else if (ctx->debug == 0) {
|
||||
return GDB_SendPacket(ctx, "W00", 3);
|
||||
} else {
|
||||
return GDB_SendStopReply(ctx, &ctx->latestDebugEvent);
|
||||
}
|
||||
}
|
||||
|
||||
static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
|
||||
|
@ -55,8 +55,10 @@ void GDB_RunMonitor(GDBServer *server)
|
||||
|
||||
if(R_FAILED(r) || idx < 2)
|
||||
break;
|
||||
else if(idx == 2)
|
||||
else if(idx == 2) {
|
||||
svcSignalEvent(server->statusUpdateReceived);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
GDBContext *ctx = &server->ctxs[idx - 3];
|
||||
@ -84,6 +86,12 @@ void GDB_RunMonitor(GDBServer *server)
|
||||
while(GDB_HandleDebugEvents(ctx) != -1) // until we've got all the remaining debug events
|
||||
svcSleepThread(1 * 1000 * 1000LL); // sleep just in case
|
||||
|
||||
// GDB doens't close the socket in extended-remote
|
||||
if (ctx->flags & GDB_FLAG_EXTENDED_REMOTE) {
|
||||
ctx->state = GDB_STATE_DETACHING;
|
||||
GDB_DetachFromProcess(ctx);
|
||||
ctx->flags &= GDB_FLAG_PROC_RESTART_MASK;
|
||||
}
|
||||
svcClearEvent(ctx->processAttachedEvent);
|
||||
ctx->eventToWaitFor = ctx->processAttachedEvent;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ Result GDB_InitializeServer(GDBServer *server)
|
||||
|
||||
server->referenceCount = 0;
|
||||
svcCreateEvent(&server->statusUpdated, RESET_ONESHOT);
|
||||
svcCreateEvent(&server->statusUpdateReceived, RESET_STICKY);
|
||||
|
||||
for(u32 i = 0; i < sizeof(server->ctxs) / sizeof(GDBContext); i++)
|
||||
GDB_InitializeContext(server->ctxs + i);
|
||||
@ -70,6 +71,7 @@ void GDB_FinalizeServer(GDBServer *server)
|
||||
server_finalize(&server->super);
|
||||
|
||||
svcCloseHandle(server->statusUpdated);
|
||||
svcCloseHandle(server->statusUpdateReceived);
|
||||
}
|
||||
|
||||
void GDB_IncrementServerReferenceCount(GDBServer *server)
|
||||
@ -189,7 +191,13 @@ int GDB_AcceptClient(GDBContext *ctx)
|
||||
int GDB_CloseClient(GDBContext *ctx)
|
||||
{
|
||||
RecursiveLock_Lock(&ctx->lock);
|
||||
svcClearEvent(ctx->parent->statusUpdateReceived);
|
||||
svcSignalEvent(ctx->parent->statusUpdated); // note: monitor will be waiting for lock
|
||||
RecursiveLock_Unlock(&ctx->lock);
|
||||
|
||||
svcWaitSynchronization(ctx->parent->statusUpdateReceived, -1LL);
|
||||
|
||||
RecursiveLock_Lock(&ctx->lock);
|
||||
GDB_DetachFromProcess(ctx);
|
||||
ctx->state = GDB_STATE_DISCONNECTED;
|
||||
RecursiveLock_Unlock(&ctx->lock);
|
||||
|
Reference in New Issue
Block a user