aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-11-03 14:56:27 +0100
committercon <qtc-committer@nokia.com>2009-11-04 19:01:11 +0100
commit608dfca7bce4984d4a5569f9bfa2dbfd24022b1a (patch)
treea20b91151a5fa2cf62f7a4e4937df09aaa770cdc
parent59413e857ea18c504f327536817147ebea294fc5 (diff)
add timeout handling for gdb commands
sometimes, commands simply don't return ... the debug message doesn't say anything which couldn't be found in the log already, but that way it is more convenient. and we kill gdb to get creator back to a defined state. Reviewed-by: hjk (cherry picked from commit 0ae60ba412afba260d0211ec5eecfe110ae8cfa2)
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp31
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h4
2 files changed, 32 insertions, 3 deletions
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index c9da4f1c281..f4b3984c286 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -193,6 +193,11 @@ GdbEngine::GdbEngine(DebuggerManager *manager) :
m_trkOptions->fromSettings(Core::ICore::instance()->settings());
m_gdbAdapter = 0;
+ m_commandTimer = new QTimer(this);
+ m_commandTimer->setSingleShot(true);
+ m_commandTimer->setInterval(COMMAND_TIMEOUT);
+ connect(m_commandTimer, SIGNAL(timeout()), SLOT(commandTimeout()));
+
// Needs no resetting in initializeVariables()
m_busy = false;
@@ -606,6 +611,9 @@ void GdbEngine::readGdbStandardError()
void GdbEngine::readGdbStandardOutput()
{
+ if (m_commandTimer->isActive())
+ m_commandTimer->start(); // Retrigger
+
int newstart = 0;
int scan = m_inbuffer.size();
@@ -796,10 +804,27 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
m_gdbAdapter->write(cmd.command.toLatin1() + "\r\n");
+ m_commandTimer->start();
+
if (cmd.flags & LosesChild)
setState(InferiorShuttingDown);
}
+void GdbEngine::commandTimeout()
+{
+ // FIXME this needs a proper message box
+ debugMessage(_("TIMED OUT WAITING FOR GDB REPLY. COMMANDS STILL IN PROGRESS:"));
+ QList<int> keys = m_cookieForToken.keys();
+ qSort(keys);
+ foreach (int key, keys) {
+ const GdbCommand &cmd = m_cookieForToken[key];
+ debugMessage(_(" %1: %2 => %3").arg(key).arg(cmd.command).arg(_(cmd.callbackName)));
+ }
+ // This is an entirely undefined state, so we just pull the emergency brake.
+ setState(EngineShuttingDown, true);
+ m_gdbProc.kill();
+}
+
void GdbEngine::handleResultRecord(GdbResponse *response)
{
//qDebug() << "TOKEN:" << response.token
@@ -927,6 +952,9 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
} else {
PENDING_DEBUG("MISSING TOKENS: " << m_cookieForToken.keys());
}
+
+ if (m_cookieForToken.isEmpty())
+ m_commandTimer->stop();
}
void GdbEngine::executeDebuggerCommand(const QString &command)
@@ -1412,7 +1440,6 @@ void GdbEngine::shutdown()
m_gdbAdapter->shutdown();
// fall-through
case AdapterStartFailed: // Adapter "did something", but it did not help
- // FIXME set some timeout?
if (m_gdbProc.state() == QProcess::Running) {
postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit));
} else {
@@ -1423,7 +1450,6 @@ void GdbEngine::shutdown()
case InferiorRunning:
case InferiorStopping:
case InferiorStopped:
- // FIXME set some timeout?
postCommand(_(m_gdbAdapter->inferiorShutdownCommand()),
NeedsStop | LosesChild, CB(handleInferiorShutdown));
break;
@@ -1432,7 +1458,6 @@ void GdbEngine::shutdown()
case InferiorShutDown:
case InferiorShutdownFailed: // Whatever
case InferiorUnrunnable:
- // FIXME set some timeout?
postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit));
setState(EngineShuttingDown); // Do it after posting the command!
break;
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 6c95977dd62..aafe05b96e0 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
+class QTimer;
class QWidget;
class QMainWindow;
QT_END_NAMESPACE
@@ -228,9 +229,12 @@ private: ////////// Gdb Command Management //////////
const QVariant &cookie = QVariant());
void postCommandHelper(const GdbCommand &cmd);
void flushQueuedCommands();
+ Q_SLOT void commandTimeout();
void setTokenBarrier();
QHash<int, GdbCommand> m_cookieForToken;
+ QTimer *m_commandTimer;
+ enum { COMMAND_TIMEOUT = 20000 };
QByteArray m_pendingConsoleStreamOutput;
QByteArray m_pendingLogStreamOutput;