diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index b404e3cd984dfeef76ce7e72ce9d2855ee355f1f..1d3adef77e7f6900c24a600330f0aa0c1b49323f 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -101,6 +101,7 @@ enum GdbCommandType GdbQuerySources, GdbAsyncOutput2, GdbStart, + GdbAttached, GdbExecRun, GdbExecRunToFunction, GdbExecStep, @@ -807,6 +808,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, case GdbStart: handleStart(record); break; + case GdbAttached: + handleAttach(); + break; case GdbInfoProc: handleInfoProc(record); 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) { const QString reason = data.findChild("reason").data(); @@ -1146,38 +1184,9 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) // // that's the "early stop" // - #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); - #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(); + handleAqcuiredInferior(); // this will "continue" if done m_waitingForBreakpointSynchronizationToContinue = true; - QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization())); return; } @@ -1471,8 +1480,16 @@ void GdbEngine::exitDebugger() if (m_gdbProc.state() == QProcess::Running) { debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1") .arg(m_gdbProc.state())); - interruptInferior(); - sendCommand("kill"); + if (q->status() != DebuggerInferiorStopped + && q->status() != DebuggerProcessStartingUp) { + QTC_ASSERT(q->status() == DebuggerInferiorRunning, + qDebug() << "STATUS ON EXITDEBUGGER: " << q->status()); + interruptInferior(); + } + if (q->startMode() == DebuggerManager::AttachExternal) + sendCommand("detach"); + else + sendCommand("kill"); sendCommand("-gdb-exit"); // 20s can easily happen when loading webkit debug information m_gdbProc.waitForFinished(20000); @@ -1627,7 +1644,7 @@ bool GdbEngine::startDebugger() } if (q->startMode() == DebuggerManager::AttachExternal) { - sendCommand("attach " + QString::number(q->m_attachedPID)); + sendCommand("attach " + QString::number(q->m_attachedPID), GdbAttached); } else { // StartInternal or StartExternal 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() { setTokenBarrier(); diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index 43b87b873c8f51b28accef6d05716de1bcf8667f..2fff81b73ee54053904ad6dbd904289134ae49c9 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -183,6 +183,8 @@ private slots: private: int terminationIndex(const QByteArray &buffer, int &length); void handleStart(const GdbResultRecord &response); + void handleAttach(); + void handleAqcuiredInferior(); void handleAsyncOutput2(const GdbMi &data); void handleAsyncOutput(const GdbMi &data); void handleResultRecord(const GdbResultRecord &response);