diff options
| author | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2009-02-20 12:33:16 +0100 |
|---|---|---|
| committer | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2009-02-27 18:04:36 +0100 |
| commit | bbaf7893cc75feba518ecd868aa005545b1f5c58 (patch) | |
| tree | af626ecc471c88f8fc7e6b325a4c04d1419d08a4 /src/plugins/debugger/gdbengine.cpp | |
| parent | d35e19060111382ac8c86c99731a0b7f860782c0 (diff) | |
| download | qt-creator-bbaf7893cc75feba518ecd868aa005545b1f5c58.tar.gz | |
"debug in terminal" feature.
includes complete refactoring of ConsoleProcess.
Diffstat (limited to 'src/plugins/debugger/gdbengine.cpp')
| -rw-r--r-- | src/plugins/debugger/gdbengine.cpp | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index dcc0382668..311608709b 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -98,6 +98,7 @@ enum GdbCommandType GdbAsyncOutput2, GdbStart, GdbAttached, + GdbStubAttached, GdbExecRun, GdbExecRunToFunction, GdbExecStep, @@ -241,6 +242,7 @@ GdbEngine::GdbEngine(DebuggerManager *parent) { q = parent; qq = parent->engineInterface(); + m_stubProc.setDebug(true); initializeVariables(); initializeConnections(); } @@ -263,6 +265,10 @@ void GdbEngine::initializeConnections() connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), q, SLOT(exitDebugger())); + connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString))); + connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted())); + connect(&m_stubProc, SIGNAL(wrapperStopped()), q, SLOT(exitDebugger())); + // Output connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)), SLOT(readDebugeeOutput(QByteArray))); @@ -543,6 +549,25 @@ void GdbEngine::handleResponse(const QByteArray &buff) } } +void GdbEngine::handleStubAttached() +{ + qq->notifyInferiorStopped(); + m_waitingForBreakpointSynchronizationToContinue = true; + handleAqcuiredInferior(); +} + +void GdbEngine::stubStarted() +{ + q->m_attachedPID = m_stubProc.applicationPID(); + qq->notifyInferiorPidChanged(q->m_attachedPID); + sendCommand("attach " + QString::number(q->m_attachedPID), GdbStubAttached); +} + +void GdbEngine::stubError(const QString &msg) +{ + QMessageBox::critical(q->mainWindow(), tr("Debugger Error"), msg); +} + void GdbEngine::readGdbStandardError() { qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError(); @@ -721,6 +746,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, const QVariant & cookie) { switch (type) { + case GdbStubAttached: + handleStubAttached(); + break; case GdbExecNext: case GdbExecStep: case GdbExecNextI: @@ -1211,6 +1239,20 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) QVariant var = QVariant::fromValue<GdbMi>(data); sendCommand("p 0", GdbAsyncOutput2, var); // dummy } else { +#ifdef Q_OS_LINUX + // For some reason, attaching to a stopped process causes *two* stops + // when trying to continue (kernel 2.6.24-23-ubuntu). + // Interestingly enough, on MacOSX no signal is delivered at all. + if (reason == QLatin1String("signal-received") + && data.findChild("signal-name").data() == "SIGSTOP") { + GdbMi frameData = data.findChild("frame"); + if (frameData.findChild("func").data() == "_start" + && frameData.findChild("from").data() == "/lib/ld-linux.so.2") { + sendCommand("-exec-continue"); + return; + } + } +#endif q->showStatusMessage(tr("Stopped: \"%1\"").arg(reason)); handleAsyncOutput2(data); } @@ -1461,23 +1503,31 @@ bool GdbEngine::startDebugger() return false; } - if (!m_outputCollector.listen()) { - QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"), - tr("Cannot set up communication with child process: %1") - .arg(m_outputCollector.errorString())); - return false; - } - - gdbArgs.prepend(QLatin1String("--tty=") + m_outputCollector.serverName()); - //gdbArgs.prepend(QLatin1String("--quiet")); gdbArgs.prepend(QLatin1String("mi")); gdbArgs.prepend(QLatin1String("-i")); - if (!q->m_workingDir.isEmpty()) - m_gdbProc.setWorkingDirectory(q->m_workingDir); - if (!q->m_environment.isEmpty()) - m_gdbProc.setEnvironment(q->m_environment); + if (q->m_useTerminal) { + m_stubProc.stop(); // We leave the console open, so recycle it now. + + m_stubProc.setWorkingDirectory(q->m_workingDir); + m_stubProc.setEnvironment(q->m_environment); + if (!m_stubProc.start(q->m_executable, q->m_processArgs)) + return false; // Error message for user is delivered via a signal. + } else { + if (!m_outputCollector.listen()) { + QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"), + tr("Cannot set up communication with child process: %1") + .arg(m_outputCollector.errorString())); + return false; + } + gdbArgs.prepend(QLatin1String("--tty=") + m_outputCollector.serverName()); + + if (!q->m_workingDir.isEmpty()) + m_gdbProc.setWorkingDirectory(q->m_workingDir); + if (!q->m_environment.isEmpty()) + m_gdbProc.setEnvironment(q->m_environment); + } #if 0 qDebug() << "Command: " << q->settings()->m_gdbCmd; @@ -1495,6 +1545,9 @@ bool GdbEngine::startDebugger() QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"), tr("Cannot start debugger: %1").arg(m_gdbProc.errorString())); m_outputCollector.shutdown(); + m_stubProc.blockSignals(true); + m_stubProc.stop(); + m_stubProc.blockSignals(false); return false; } @@ -1575,7 +1628,7 @@ bool GdbEngine::startDebugger() if (q->startMode() == DebuggerManager::AttachExternal) { sendCommand("attach " + QString::number(q->m_attachedPID), GdbAttached); - } else { + } else if (!q->m_useTerminal) { // StartInternal or StartExternal sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); //sendCommand("file " + fileName, GdbFileExecAndSymbols); |
