Debugger: Add poll interrupting

This commit is contained in:
Vicki Pfau 2022-04-03 02:49:05 -07:00
parent 43f64852ad
commit bc9bb43f88
9 changed files with 60 additions and 7 deletions

View File

@ -85,6 +85,7 @@ struct mCoreThreadInternal {
struct mCoreSync sync; struct mCoreSync sync;
struct mCoreRewindContext rewind; struct mCoreRewindContext rewind;
struct mCore* core;
}; };
#endif #endif

View File

@ -143,6 +143,8 @@ struct mDebugger {
void (*update)(struct mDebugger*); void (*update)(struct mDebugger*);
void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
void (*custom)(struct mDebugger*); void (*custom)(struct mDebugger*);
void (*interrupt)(struct mDebugger*);
}; };
struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore*); struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore*);

View File

@ -77,6 +77,7 @@ struct CLIDebuggerBackend {
void (*lineAppend)(struct CLIDebuggerBackend*, const char* line); void (*lineAppend)(struct CLIDebuggerBackend*, const char* line);
const char* (*historyLast)(struct CLIDebuggerBackend*, size_t* len); const char* (*historyLast)(struct CLIDebuggerBackend*, size_t* len);
void (*historyAppend)(struct CLIDebuggerBackend*, const char* line); void (*historyAppend)(struct CLIDebuggerBackend*, const char* line);
void (*interrupt)(struct CLIDebuggerBackend*);
}; };
struct CLIDebugger { struct CLIDebugger {
@ -87,6 +88,7 @@ struct CLIDebugger {
int traceRemaining; int traceRemaining;
struct VFile* traceVf; struct VFile* traceVf;
bool skipStatus;
}; };
void CLIDebuggerCreate(struct CLIDebugger*); void CLIDebuggerCreate(struct CLIDebugger*);

View File

@ -92,6 +92,13 @@ static void _wait(struct mCoreThreadInternal* threadContext) {
MutexUnlock(&threadContext->sync.audioBufferMutex); MutexUnlock(&threadContext->sync.audioBufferMutex);
} }
if (threadContext->core && threadContext->core->debugger) {
struct mDebugger* debugger = threadContext->core->debugger;
if (debugger->interrupt) {
debugger->interrupt(debugger);
}
}
MutexLock(&threadContext->stateMutex); MutexLock(&threadContext->stateMutex);
ConditionWake(&threadContext->stateCond); ConditionWake(&threadContext->stateCond);
} }
@ -216,6 +223,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
} }
core->reset(core); core->reset(core);
threadContext->impl->core = core;
_changeState(threadContext->impl, mTHREAD_RUNNING, true); _changeState(threadContext->impl, mTHREAD_RUNNING, true);
if (threadContext->resetCallback) { if (threadContext->resetCallback) {
@ -519,7 +527,11 @@ void mCoreThreadContinue(struct mCoreThread* threadContext) {
MutexLock(&threadContext->impl->stateMutex); MutexLock(&threadContext->impl->stateMutex);
--threadContext->impl->interruptDepth; --threadContext->impl->interruptDepth;
if (threadContext->impl->interruptDepth < 1 && mCoreThreadIsActive(threadContext)) { if (threadContext->impl->interruptDepth < 1 && mCoreThreadIsActive(threadContext)) {
if (threadContext->impl->requested) {
threadContext->impl->state = mTHREAD_REQUEST; threadContext->impl->state = mTHREAD_REQUEST;
} else {
threadContext->impl->state = mTHREAD_RUNNING;
}
ConditionWake(&threadContext->impl->stateCond); ConditionWake(&threadContext->impl->stateCond);
} }
MutexUnlock(&threadContext->impl->stateMutex); MutexUnlock(&threadContext->impl->stateMutex);

View File

@ -995,20 +995,32 @@ static void _commandLine(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
const char* line; const char* line;
size_t len; size_t len;
if (cliDebugger->skipStatus) {
cliDebugger->skipStatus = false;
} else {
_printStatus(cliDebugger, 0); _printStatus(cliDebugger, 0);
}
while (debugger->state == DEBUGGER_PAUSED) { while (debugger->state == DEBUGGER_PAUSED) {
line = cliDebugger->backend->readline(cliDebugger->backend, &len); line = cliDebugger->backend->readline(cliDebugger->backend, &len);
if (!line || len == 0) { if (!line || len == 0) {
debugger->state = DEBUGGER_SHUTDOWN; debugger->state = DEBUGGER_SHUTDOWN;
return; return;
} }
if (line[0] == '\033') {
cliDebugger->skipStatus = true;
return;
}
if (line[0] == '\n') { if (line[0] == '\n') {
line = cliDebugger->backend->historyLast(cliDebugger->backend, &len); line = cliDebugger->backend->historyLast(cliDebugger->backend, &len);
if (line && len) { if (line && len) {
CLIDebuggerRunCommand(cliDebugger, line, len); CLIDebuggerRunCommand(cliDebugger, line, len);
} }
} else {
if (line[0] == '#') {
cliDebugger->skipStatus = true;
} else { } else {
CLIDebuggerRunCommand(cliDebugger, line, len); CLIDebuggerRunCommand(cliDebugger, line, len);
}
cliDebugger->backend->historyAppend(cliDebugger->backend, line); cliDebugger->backend->historyAppend(cliDebugger->backend, line);
} }
} }
@ -1019,6 +1031,7 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r
if (cliDebugger->traceRemaining > 0) { if (cliDebugger->traceRemaining > 0) {
cliDebugger->traceRemaining = 0; cliDebugger->traceRemaining = 0;
} }
cliDebugger->skipStatus = false;
switch (reason) { switch (reason) {
case DEBUGGER_ENTER_MANUAL: case DEBUGGER_ENTER_MANUAL:
case DEBUGGER_ENTER_ATTACHED: case DEBUGGER_ENTER_ATTACHED:
@ -1077,6 +1090,7 @@ static void _cliDebuggerInit(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
cliDebugger->traceRemaining = 0; cliDebugger->traceRemaining = 0;
cliDebugger->traceVf = NULL; cliDebugger->traceVf = NULL;
cliDebugger->skipStatus = false;
cliDebugger->backend->init(cliDebugger->backend); cliDebugger->backend->init(cliDebugger->backend);
if (cliDebugger->system && cliDebugger->system->init) { if (cliDebugger->system && cliDebugger->system->init) {
cliDebugger->system->init(cliDebugger->system); cliDebugger->system->init(cliDebugger->system);
@ -1119,6 +1133,13 @@ static void _cliDebuggerCustom(struct mDebugger* debugger) {
} }
} }
static void _cliDebuggerInterrupt(struct mDebugger* debugger) {
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
if (cliDebugger->backend->interrupt) {
cliDebugger->backend->interrupt(cliDebugger->backend);
}
}
void CLIDebuggerCreate(struct CLIDebugger* debugger) { void CLIDebuggerCreate(struct CLIDebugger* debugger) {
debugger->d.init = _cliDebuggerInit; debugger->d.init = _cliDebuggerInit;
debugger->d.deinit = _cliDebuggerDeinit; debugger->d.deinit = _cliDebuggerDeinit;
@ -1126,6 +1147,7 @@ void CLIDebuggerCreate(struct CLIDebugger* debugger) {
debugger->d.paused = _commandLine; debugger->d.paused = _commandLine;
debugger->d.update = NULL; debugger->d.update = NULL;
debugger->d.entered = _reportEntry; debugger->d.entered = _reportEntry;
debugger->d.interrupt = _cliDebuggerInterrupt;
debugger->d.type = DEBUGGER_CLI; debugger->d.type = DEBUGGER_CLI;
debugger->system = NULL; debugger->system = NULL;

View File

@ -761,12 +761,13 @@ size_t _parseGDBMessage(struct GDBStub* stub, const char* message) {
void GDBStubCreate(struct GDBStub* stub) { void GDBStubCreate(struct GDBStub* stub) {
stub->socket = INVALID_SOCKET; stub->socket = INVALID_SOCKET;
stub->connection = INVALID_SOCKET; stub->connection = INVALID_SOCKET;
stub->d.init = 0; stub->d.init = NULL;
stub->d.deinit = _gdbStubDeinit; stub->d.deinit = _gdbStubDeinit;
stub->d.paused = _gdbStubWait; stub->d.paused = _gdbStubWait;
stub->d.update = _gdbStubUpdate; stub->d.update = _gdbStubUpdate;
stub->d.entered = _gdbStubEntered; stub->d.entered = _gdbStubEntered;
stub->d.custom = _gdbStubPoll; stub->d.custom = _gdbStubPoll;
stub->d.interrupt = NULL;
stub->d.type = DEBUGGER_GDB; stub->d.type = DEBUGGER_GDB;
stub->untilPoll = GDB_STUB_INTERVAL; stub->untilPoll = GDB_STUB_INTERVAL;
stub->lineAck = GDB_ACK_PENDING; stub->lineAck = GDB_ACK_PENDING;

View File

@ -152,7 +152,7 @@ void _CLIDebuggerEditLineHistoryAppend(struct CLIDebuggerBackend* be, const char
} }
struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) { struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) {
struct CLIDebuggerEditLineBackend* elbe = malloc(sizeof(*elbe)); struct CLIDebuggerEditLineBackend* elbe = calloc(1, sizeof(*elbe));
elbe->d.printf = _CLIDebuggerEditLinePrintf; elbe->d.printf = _CLIDebuggerEditLinePrintf;
elbe->d.init = _CLIDebuggerEditLineInit; elbe->d.init = _CLIDebuggerEditLineInit;
elbe->d.deinit = _CLIDebuggerEditLineDeinit; elbe->d.deinit = _CLIDebuggerEditLineDeinit;
@ -160,5 +160,6 @@ struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) {
elbe->d.lineAppend = _CLIDebuggerEditLineLineAppend; elbe->d.lineAppend = _CLIDebuggerEditLineLineAppend;
elbe->d.historyLast = _CLIDebuggerEditLineHistoryLast; elbe->d.historyLast = _CLIDebuggerEditLineHistoryLast;
elbe->d.historyAppend = _CLIDebuggerEditLineHistoryAppend; elbe->d.historyAppend = _CLIDebuggerEditLineHistoryAppend;
elbe->d.interrupt = NULL;
return &elbe->d; return &elbe->d;
} }

View File

@ -26,6 +26,7 @@ DebuggerConsoleController::DebuggerConsoleController(QObject* parent)
m_backend.d.lineAppend = lineAppend; m_backend.d.lineAppend = lineAppend;
m_backend.d.historyLast = historyLast; m_backend.d.historyLast = historyLast;
m_backend.d.historyAppend = historyAppend; m_backend.d.historyAppend = historyAppend;
m_backend.d.interrupt = interrupt;
m_backend.self = this; m_backend.self = this;
CLIDebuggerCreate(&m_cliDebugger); CLIDebuggerCreate(&m_cliDebugger);
@ -90,7 +91,6 @@ void DebuggerConsoleController::deinit(struct CLIDebuggerBackend* be) {
const char* DebuggerConsoleController::readLine(struct CLIDebuggerBackend* be, size_t* len) { const char* DebuggerConsoleController::readLine(struct CLIDebuggerBackend* be, size_t* len) {
Backend* consoleBe = reinterpret_cast<Backend*>(be); Backend* consoleBe = reinterpret_cast<Backend*>(be);
DebuggerConsoleController* self = consoleBe->self; DebuggerConsoleController* self = consoleBe->self;
CoreController::Interrupter interrupter(self->m_gameController);
QMutexLocker lock(&self->m_mutex); QMutexLocker lock(&self->m_mutex);
while (self->m_lines.isEmpty()) { while (self->m_lines.isEmpty()) {
self->m_cond.wait(&self->m_mutex); self->m_cond.wait(&self->m_mutex);
@ -132,6 +132,17 @@ void DebuggerConsoleController::historyAppend(struct CLIDebuggerBackend* be, con
self->m_history.append(QString::fromUtf8(line)); self->m_history.append(QString::fromUtf8(line));
} }
void DebuggerConsoleController::interrupt(struct CLIDebuggerBackend* be) {
Backend* consoleBe = reinterpret_cast<Backend*>(be);
DebuggerConsoleController* self = consoleBe->self;
QMutexLocker lock(&self->m_mutex);
self->m_cond.wakeOne();
if (!self->m_lines.isEmpty()) {
return;
}
self->m_lines.append("\033");
}
void DebuggerConsoleController::historyLoad() { void DebuggerConsoleController::historyLoad() {
QFile log(ConfigController::configDir() + "/cli_history.log"); QFile log(ConfigController::configDir() + "/cli_history.log");
QStringList history; QStringList history;

View File

@ -46,6 +46,7 @@ private:
static void lineAppend(struct CLIDebuggerBackend* be, const char* line); static void lineAppend(struct CLIDebuggerBackend* be, const char* line);
static const char* historyLast(struct CLIDebuggerBackend* be, size_t* len); static const char* historyLast(struct CLIDebuggerBackend* be, size_t* len);
static void historyAppend(struct CLIDebuggerBackend* be, const char* line); static void historyAppend(struct CLIDebuggerBackend* be, const char* line);
static void interrupt(struct CLIDebuggerBackend* be);
CLIDebugger m_cliDebugger{}; CLIDebugger m_cliDebugger{};