make attach & detach work

This commit is contained in:
Oswald Buddenhagen
2009-02-18 15:27:56 +01:00
parent f5cb9d11f0
commit ed3453e8ea
2 changed files with 83 additions and 33 deletions

View File

@@ -101,6 +101,7 @@ enum GdbCommandType
GdbQuerySources, GdbQuerySources,
GdbAsyncOutput2, GdbAsyncOutput2,
GdbStart, GdbStart,
GdbAttached,
GdbExecRun, GdbExecRun,
GdbExecRunToFunction, GdbExecRunToFunction,
GdbExecStep, GdbExecStep,
@@ -807,6 +808,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
case GdbStart: case GdbStart:
handleStart(record); handleStart(record);
break; break;
case GdbAttached:
handleAttach();
break;
case GdbInfoProc: case GdbInfoProc:
handleInfoProc(record); handleInfoProc(record);
break; break;
@@ -1109,6 +1113,40 @@ static bool isStoppedReason(const QString &reason)
; ;
} }
void GdbEngine::handleAqcuiredInferior()
{
#if defined(Q_OS_WIN)
sendCommand("info thread", GdbInfoThreads);
#endif
#if defined(Q_OS_LINUX)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc, QVariant(), true);
#endif
reloadSourceFiles();
tryLoadCustomDumpers();
// intentionally after tryLoadCustomDumpers(),
// otherwise we'd interupt solib loading.
if (qq->wantsAllPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 0");
sendCommand("sharedlibrary .*");
} else if (qq->wantsSelectedPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 1");
sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern());
} else if (qq->wantsNoPluginBreakpoints()) {
// should be like that already
sendCommand("set auto-solib-add off");
sendCommand("set stop-on-solib-events 0");
}
// nicer to see a bit of the world we live in
reloadModules();
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
}
void GdbEngine::handleAsyncOutput(const GdbMi &data) void GdbEngine::handleAsyncOutput(const GdbMi &data)
{ {
const QString reason = data.findChild("reason").data(); const QString reason = data.findChild("reason").data();
@@ -1146,38 +1184,9 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
// //
// that's the "early stop" // that's the "early stop"
// //
#if defined(Q_OS_WIN) handleAqcuiredInferior();
sendCommand("info thread", GdbInfoThreads);
#endif
#if defined(Q_OS_LINUX)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc);
#endif
reloadSourceFiles();
tryLoadCustomDumpers();
// intentionally after tryLoadCustomDumpers(),
// otherwise we'd interupt solib loading.
if (qq->wantsAllPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 0");
sendCommand("sharedlibrary .*");
} else if (qq->wantsSelectedPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 1");
sendCommand("sharedlibrary "+qq->selectedPluginBreakpointsPattern());
} else if (qq->wantsNoPluginBreakpoints()) {
// should be like that already
sendCommand("set auto-solib-add off");
sendCommand("set stop-on-solib-events 0");
}
// nicer to see a bit of the world we live in
reloadModules();
// this will "continue" if done // this will "continue" if done
m_waitingForBreakpointSynchronizationToContinue = true; m_waitingForBreakpointSynchronizationToContinue = true;
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
return; return;
} }
@@ -1471,7 +1480,15 @@ void GdbEngine::exitDebugger()
if (m_gdbProc.state() == QProcess::Running) { if (m_gdbProc.state() == QProcess::Running) {
debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1") debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
.arg(m_gdbProc.state())); .arg(m_gdbProc.state()));
if (q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
qDebug() << "STATUS ON EXITDEBUGGER: " << q->status());
interruptInferior(); interruptInferior();
}
if (q->startMode() == DebuggerManager::AttachExternal)
sendCommand("detach");
else
sendCommand("kill"); sendCommand("kill");
sendCommand("-gdb-exit"); sendCommand("-gdb-exit");
// 20s can easily happen when loading webkit debug information // 20s can easily happen when loading webkit debug information
@@ -1627,7 +1644,7 @@ bool GdbEngine::startDebugger()
} }
if (q->startMode() == DebuggerManager::AttachExternal) { if (q->startMode() == DebuggerManager::AttachExternal) {
sendCommand("attach " + QString::number(q->m_attachedPID)); sendCommand("attach " + QString::number(q->m_attachedPID), GdbAttached);
} else { } else {
// StartInternal or StartExternal // StartInternal or StartExternal
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
@@ -1680,6 +1697,37 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
} }
} }
void GdbEngine::handleAttach()
{
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Attached to running process. Stopped."));
handleAqcuiredInferior();
q->resetLocation();
//
// Stack
//
qq->stackHandler()->setCurrentIndex(0);
updateLocals(); // Quick shot
sendSynchronizedCommand("-stack-list-frames", StackListFrames);
if (supportsThreads())
sendSynchronizedCommand("-thread-list-ids", StackListThreads, 0);
//
// Disassembler
//
// XXX we have no data here ...
//m_address = data.findChild("frame").findChild("addr").data();
//qq->reloadDisassembler();
//
// Registers
//
qq->reloadRegisters();
}
void GdbEngine::stepExec() void GdbEngine::stepExec()
{ {
setTokenBarrier(); setTokenBarrier();

View File

@@ -183,6 +183,8 @@ private slots:
private: private:
int terminationIndex(const QByteArray &buffer, int &length); int terminationIndex(const QByteArray &buffer, int &length);
void handleStart(const GdbResultRecord &response); void handleStart(const GdbResultRecord &response);
void handleAttach();
void handleAqcuiredInferior();
void handleAsyncOutput2(const GdbMi &data); void handleAsyncOutput2(const GdbMi &data);
void handleAsyncOutput(const GdbMi &data); void handleAsyncOutput(const GdbMi &data);
void handleResultRecord(const GdbResultRecord &response); void handleResultRecord(const GdbResultRecord &response);