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 mCoreRewindContext rewind;
struct mCore* core;
};
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,6 +26,7 @@ DebuggerConsoleController::DebuggerConsoleController(QObject* parent)
m_backend.d.lineAppend = lineAppend;
m_backend.d.historyLast = historyLast;
m_backend.d.historyAppend = historyAppend;
m_backend.d.interrupt = interrupt;
m_backend.self = this;
CLIDebuggerCreate(&m_cliDebugger);
@ -90,7 +91,6 @@ void DebuggerConsoleController::deinit(struct CLIDebuggerBackend* be) {
const char* DebuggerConsoleController::readLine(struct CLIDebuggerBackend* be, size_t* len) {
Backend* consoleBe = reinterpret_cast<Backend*>(be);
DebuggerConsoleController* self = consoleBe->self;
CoreController::Interrupter interrupter(self->m_gameController);
QMutexLocker lock(&self->m_mutex);
while (self->m_lines.isEmpty()) {
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));
}
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() {
QFile log(ConfigController::configDir() + "/cli_history.log");
QStringList history;

View File

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