mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add poll interrupting
This commit is contained in:
parent
43f64852ad
commit
bc9bb43f88
|
@ -85,6 +85,7 @@ struct mCoreThreadInternal {
|
|||
|
||||
struct mCoreSync sync;
|
||||
struct mCoreRewindContext rewind;
|
||||
struct mCore* core;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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{};
|
||||
|
||||
|
|
Loading…
Reference in New Issue