summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcon <qtc-committer@nokia.com>2010-01-06 15:52:14 +0100
committercon <qtc-committer@nokia.com>2010-01-06 15:57:10 +0100
commitdb68ca5b8d7454eb0429dc169d3cfff66c7226d4 (patch)
treeed96f67fa4ded80c69147030c4dacf3fad721907
parent0de840cb43bf40cb58530e41e0b1c29397d34827 (diff)
downloadqt-creator-db68ca5b8d7454eb0429dc169d3cfff66c7226d4.tar.gz
debugger: gracefully handle commands that might not produce output
(cherry picked from commit 1324a1c6004e1f0702d46a9adb4dc69631247e1a) Conflicts: src/plugins/debugger/gdb/gdbengine.cpp src/plugins/debugger/gdb/gdbengine.h
-rw-r--r--src/plugins/debugger/debuggermanager.cpp7
-rw-r--r--src/plugins/debugger/debuggermanager.h8
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp51
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h14
4 files changed, 59 insertions, 21 deletions
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index f14d10723e..9a836aa899 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -1541,13 +1541,14 @@ void DebuggerManager::setSessionValue(const QString &name, const QVariant &value
emit setSessionValueRequested(name, value);
}
-void DebuggerManager::showMessageBox(int icon,
- const QString &title, const QString &text)
+QMessageBox *DebuggerManager::showMessageBox(int icon, const QString &title,
+ const QString &text, int buttons)
{
QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
- title, text, QMessageBox::NoButton, mainWindow());
+ title, text, QMessageBox::StandardButtons(buttons), mainWindow());
mb->setAttribute(Qt::WA_DeleteOnClose);
mb->show();
+ return mb;
}
DebuggerState DebuggerManager::state() const
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 05639618b2..045d99fe29 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -39,11 +39,12 @@
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
+class QAbstractItemModel;
class QAction;
+class QDebug;
class QDockWidget;
class QLabel;
-class QDebug;
-class QAbstractItemModel;
+class QMessageBox;
class QPoint;
class QVariant;
QT_END_NAMESPACE
@@ -177,7 +178,8 @@ public:
DebuggerStartParametersPtr startParameters() const;
qint64 inferiorPid() const;
- void showMessageBox(int icon, const QString &title, const QString &text);
+ QMessageBox *showMessageBox(int icon, const QString &title, const QString &text,
+ int buttons = 0);
bool debuggerActionsEnabled() const;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index a2f97db8f2..070ab9a82c 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -617,7 +617,7 @@ void GdbEngine::readGdbStandardError()
void GdbEngine::readGdbStandardOutput()
{
- if (m_commandTimer->isActive())
+ if (m_commandTimer->isActive())
m_commandTimer->start(); // Retrigger
int newstart = 0;
@@ -816,19 +816,48 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
setState(InferiorShuttingDown);
}
+int GdbEngine::commandTimeoutTime() const
+{
+ int time = theDebuggerAction(GdbWatchdogTimeout)->value().toInt();
+ return 1000 * qMax(20, time);
+}
+
void GdbEngine::commandTimeout()
{
- // FIXME this needs a proper message box
- debugMessage(_("TIMED OUT WAITING FOR GDB REPLY. COMMANDS STILL IN PROGRESS:"));
+ qDebug("TIMEOUT");
QList<int> keys = m_cookieForToken.keys();
qSort(keys);
+ bool killIt = false;
foreach (int key, keys) {
- const GdbCommand &cmd = m_cookieForToken[key];
+ const GdbCommand &cmd = m_cookieForToken.value(key);
+ if (!(cmd.flags & NonCriticalResponse))
+ killIt = true;
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();
+ if (killIt) {
+ debugMessage(_("TIMED OUT WAITING FOR GDB REPLY. COMMANDS STILL IN PROGRESS:"));
+ int timeOut = m_commandTimer->interval();
+ //m_commandTimer->stop();
+ QString msg = tr("The gdb process has not produced any response "
+ "to a command within %1 seconds. This may been it is stuck "
+ "in an endless loop or taking longer than expected to perform "
+ "the operation it was reqested.\nYou have a choice of waiting "
+ "longer or abort debugging.").arg(timeOut);
+ QMessageBox *mb = showMessageBox(QMessageBox::Critical,
+ tr("Gdb not responding"), msg,
+ QMessageBox::Ok | QMessageBox::Cancel);
+ mb->button(QMessageBox::Cancel)->setText(tr("Give gdb more time"));
+ mb->button(QMessageBox::Ok)->setText(tr("Stop debugging"));
+ if (mb->exec() == QMessageBox::Ok) {
+ debugMessage(_("KILLING DEBUGGER AS REQUESTED BY USER"));
+ // This is an undefined state, so we just pull the emergency brake.
+ manager()->watchHandler()->endCycle();
+ setState(EngineShuttingDown, true);
+ m_gdbProc.kill();
+ } else {
+ debugMessage(_("CONTINUE DEBUGGER AS REQUESTED BY USER"));
+ }
+ }
}
void GdbEngine::handleResultRecord(GdbResponse *response)
@@ -2960,7 +2989,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
<<',' << addr << ',' << (dumpChildren ? "1" : "0")
<< ',' << extraArgs.join(QString(_c(','))) << ')';
- postCommand(cmd, WatchUpdate | EmbedToken);
+ postCommand(cmd, WatchUpdate | EmbedToken | NonCriticalResponse);
showStatusMessage(msgRetrievingWatchData(m_pendingRequests + 1), 10000);
@@ -4347,6 +4376,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
SLOT(readGdbStandardError()));
debugMessage(_("GDB STARTED, INITIALIZING IT"));
+ m_commandTimer->setInterval(commandTimeoutTime());
postCommand(_("show version"), CB(handleShowVersion));
postCommand(_("-interpreter-exec console \"help bb\""),
@@ -4573,9 +4603,10 @@ void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const
opts->push_back(new TrkOptionsPage(m_trkOptions));
}
-void GdbEngine::showMessageBox(int icon, const QString &title, const QString &text)
+QMessageBox * GdbEngine::showMessageBox(int icon, const QString &title,
+ const QString &text, int buttons)
{
- m_manager->showMessageBox(icon, title, text);
+ return m_manager->showMessageBox(icon, title, text, buttons);
}
bool GdbEngine::isSynchroneous() const
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 1d6b1666eb..3707bf66cc 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -47,11 +47,12 @@
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
-class QAction;
class QAbstractItemModel;
+class QAction;
+class QMainWindow;
+class QMessageBox;
class QTimer;
class QWidget;
-class QMainWindow;
QT_END_NAMESPACE
namespace Debugger {
@@ -176,10 +177,11 @@ private: ////////// Gdb Command Management //////////
Discardable = 2, // No need to wait for the reply before continuing inferior
RebuildModel = 4, // Trigger model rebuild when no such commands are pending any more
WatchUpdate = Discardable | RebuildModel,
- EmbedToken = 8, // Expand %1 in the command to the command token
+ NonCriticalResponse = 8, // We can live without recieving an answer
RunRequest = 16, // Callback expects GdbResultRunning instead of GdbResultDone
ExitRequest = 32, // Callback expects GdbResultExit instead of GdbResultDone
- LosesChild = 64 // Auto-set inferior shutdown related states
+ LosesChild = 64, // Auto-set inferior shutdown related states
+ EmbedToken = 128 // Expand %1 in the command to the command token
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
private:
@@ -233,6 +235,7 @@ private: ////////// Gdb Command Management //////////
void setTokenBarrier();
QHash<int, GdbCommand> m_cookieForToken;
+ int commandTimeoutTime() const;
QTimer *m_commandTimer;
QByteArray m_pendingConsoleStreamOutput;
@@ -476,7 +479,8 @@ private: ////////// Dumper Management //////////
private: ////////// Convenience Functions //////////
QString errorMessage(QProcess::ProcessError error);
- void showMessageBox(int icon, const QString &title, const QString &text);
+ QMessageBox *showMessageBox(int icon, const QString &title, const QString &text,
+ int buttons = 0);
void debugMessage(const QString &msg);
QMainWindow *mainWindow() const;
};