forked from qt-creator/qt-creator
debugger: rework plain gdb shutdown logic
This commit is contained in:
@@ -57,6 +57,7 @@ namespace Internal {
|
||||
PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||
: AbstractGdbAdapter(engine, parent)
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
|
||||
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
|
||||
this, SIGNAL(error(QProcess::ProcessError)));
|
||||
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
|
||||
@@ -64,9 +65,9 @@ PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
|
||||
this, SIGNAL(readyReadStandardError()));
|
||||
connect(&m_gdbProc, SIGNAL(started()),
|
||||
this, SIGNAL(adapterStarted()));
|
||||
this, SLOT(handleGdbStarted()));
|
||||
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||
this, SLOT(handleFinished(int, QProcess::ExitStatus)));
|
||||
this, SLOT(handleGdbFinished(int, QProcess::ExitStatus)));
|
||||
|
||||
m_stubProc.setMode(Core::Utils::ConsoleProcess::Debug);
|
||||
#ifdef Q_OS_UNIX
|
||||
@@ -84,6 +85,8 @@ PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||
|
||||
void PlainGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
|
||||
setState(AdapterStarting);
|
||||
debugMessage(_("TRYING TO START ADAPTER"));
|
||||
m_startParameters = sp;
|
||||
|
||||
@@ -121,10 +124,20 @@ void PlainGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
|
||||
m_gdbProc.start(location, gdbArgs);
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::handleGdbStarted()
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
|
||||
setState(AdapterStarted);
|
||||
emit adapterStarted();
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::prepareInferior()
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
|
||||
setState(InferiorPreparing);
|
||||
if (!m_startParameters->processArgs.isEmpty())
|
||||
m_engine->postCommand(_("-exec-arguments ") + m_startParameters->processArgs.join(_(" ")));
|
||||
m_engine->postCommand(_("-exec-arguments ")
|
||||
+ m_startParameters->processArgs.join(_(" ")));
|
||||
QFileInfo fi(m_engine->startParameters().executable);
|
||||
m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()),
|
||||
CB(handleFileExecAndSymbols));
|
||||
@@ -132,18 +145,23 @@ void PlainGdbAdapter::prepareInferior()
|
||||
|
||||
void PlainGdbAdapter::handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &)
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorPreparing, qDebug() << state());
|
||||
if (response.resultClass == GdbResultDone) {
|
||||
//m_breakHandler->clearBreakMarkers();
|
||||
setState(InferiorPrepared);
|
||||
emit inferiorPrepared();
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
QString msg = tr("Starting executable failed:\n") +
|
||||
__(response.data.findChild("msg").data());
|
||||
setState(InferiorPreparationFailed);
|
||||
emit inferiorPreparationFailed(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::startInferior()
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorPrepared, qDebug() << state());
|
||||
setState(InferiorStarting);
|
||||
m_engine->postCommand(_("-exec-run"), CB(handleExecRun));
|
||||
/*
|
||||
#ifdef Q_OS_MAC
|
||||
@@ -163,6 +181,7 @@ void PlainGdbAdapter::startInferior()
|
||||
|
||||
void PlainGdbAdapter::handleInfoTarget(const GdbResultRecord &response, const QVariant &)
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
|
||||
#if defined(Q_OS_MAC)
|
||||
Q_UNUSED(response)
|
||||
#else
|
||||
@@ -190,13 +209,16 @@ void PlainGdbAdapter::handleInfoTarget(const GdbResultRecord &response, const QV
|
||||
|
||||
void PlainGdbAdapter::handleExecRun(const GdbResultRecord &response, const QVariant &)
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
||||
if (response.resultClass == GdbResultRunning) {
|
||||
setState(InferiorStarted);
|
||||
emit inferiorStarted();
|
||||
} else {
|
||||
QTC_ASSERT(response.resultClass == GdbResultError, /**/);
|
||||
const QByteArray &msg = response.data.findChild("msg").data();
|
||||
//QTC_ASSERT(status() == DebuggerInferiorRunning, /**/);
|
||||
//interruptInferior();
|
||||
setState(InferiorStartFailed);
|
||||
emit inferiorStartFailed(msg);
|
||||
}
|
||||
}
|
||||
@@ -221,26 +243,57 @@ void PlainGdbAdapter::interruptInferior()
|
||||
|
||||
void PlainGdbAdapter::shutdownAdapter()
|
||||
{
|
||||
m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
|
||||
// 20s can easily happen when loading webkit debug information
|
||||
if (!m_gdbProc.waitForFinished(20000)) {
|
||||
debugMessage(_("FORCING TERMINATION: %1")
|
||||
.arg(state()));
|
||||
m_gdbProc.terminate();
|
||||
m_gdbProc.waitForFinished(20000);
|
||||
if (state() == InferiorStarted) {
|
||||
setState(InferiorShuttingDown);
|
||||
m_engine->postCommand(_("kill"), CB(handleKill));
|
||||
return;
|
||||
}
|
||||
|
||||
if (state() != QProcess::NotRunning) {
|
||||
debugMessage(_("PROBLEM STOPPING DEBUGGER: STATE %1")
|
||||
if (state() == InferiorShutDown) {
|
||||
setState(AdapterShuttingDown);
|
||||
m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if (state() == InferiorShutdownFailed) {
|
||||
m_gdbProc.terminate();
|
||||
// 20s can easily happen when loading webkit debug information
|
||||
m_gdbProc.waitForFinished(20000);
|
||||
setState(AdapterShuttingDown);
|
||||
debugMessage(_("FORCING TERMINATION: %1")
|
||||
.arg(state()));
|
||||
m_gdbProc.kill();
|
||||
if (state() != QProcess::NotRunning) {
|
||||
debugMessage(_("PROBLEM STOPPING DEBUGGER: STATE %1")
|
||||
.arg(state()));
|
||||
m_gdbProc.kill();
|
||||
}
|
||||
m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::handleKill(const GdbResultRecord &response, const QVariant &)
|
||||
{
|
||||
if (response.resultClass == GdbResultDone) {
|
||||
setState(InferiorShutDown);
|
||||
emit inferiorShutDown();
|
||||
shutdownAdapter(); // re-iterate...
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
QString msg = tr("Inferior process could not be stopped:\n") +
|
||||
__(response.data.findChild("msg").data());
|
||||
setState(InferiorShutdownFailed);
|
||||
emit inferiorShutdownFailed(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant &)
|
||||
{
|
||||
if (response.resultClass == GdbResultDone) {
|
||||
emit adapterShutDown();
|
||||
// don't set state here, this will be handled in handleGdbFinished()
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
QString msg = tr("Gdb process could not be stopped:\n") +
|
||||
__(response.data.findChild("msg").data());
|
||||
@@ -248,9 +301,11 @@ void PlainGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant
|
||||
}
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::handleFinished(int, QProcess::ExitStatus)
|
||||
void PlainGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
|
||||
{
|
||||
debugMessage(_("GDB PROESS FINISHED"));
|
||||
debugMessage(_("GDB PROESS FINISHED"));
|
||||
setState(AdapterNotRunning);
|
||||
emit adapterShutDown();
|
||||
}
|
||||
|
||||
void PlainGdbAdapter::shutdownInferior()
|
||||
@@ -287,5 +342,6 @@ void PlainGdbAdapter::emitAdapterStartFailed(const QString &msg)
|
||||
m_stubProc.blockSignals(false);
|
||||
emit adapterStartFailed(msg);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
Reference in New Issue
Block a user