diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index 3fe37b9500c60db01fd754b551a35110342a7741..7a8d5a007eb94e5e912c23123c8ea07434c870f9 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -36,11 +36,16 @@
 #include <QtCore/QTextCodec>
 #include <QtCore/QFileInfo>
 #include <QtCore/QDir>
+#include <QtGui/QMessageBox>
 
 #include <QtGui/QApplication>
 
 #include <limits.h>
 
+#ifdef Q_OS_UNIX
+#    include <unistd.h>
+#endif
+
 enum { debug = 0 };
 enum { syncDebug = 0 };
 
@@ -48,6 +53,30 @@ enum { defaultMaxHangTimerCount = 10 };
 
 namespace Utils {
 
+// A special QProcess derivative allowing for terminal control.
+class TerminalControllingProcess : public QProcess {
+public:
+    TerminalControllingProcess() : m_flags(0) {}
+
+    unsigned flags() const { return m_flags; }
+    void setFlags(unsigned tc) { m_flags = tc; }
+
+protected:
+    virtual void setupChildProcess();
+
+private:
+    unsigned m_flags;
+};
+
+void TerminalControllingProcess::setupChildProcess()
+{
+#ifdef Q_OS_UNIX
+    // Disable terminal by becoming a session leader.
+    if (m_flags & SynchronousProcess::UnixTerminalDisabled)
+        setsid();
+#endif
+}
+
 // ----------- SynchronousProcessResponse
 SynchronousProcessResponse::SynchronousProcessResponse() :
    result(StartFailed),
@@ -63,6 +92,25 @@ void SynchronousProcessResponse::clear()
     stdErr.clear();
 }
 
+QString SynchronousProcessResponse::exitMessage(const QString &binary, int timeoutMS) const
+{
+    switch (result) {
+    case Finished:
+        return SynchronousProcess::tr("The command '%1' finished successfully.").arg(binary);
+    case FinishedError:
+        return SynchronousProcess::tr("The command '%1' terminated with exit code %2.").arg(binary).arg(exitCode);
+        break;
+    case TerminatedAbnormally:
+        return SynchronousProcess::tr("The command '%1' terminated abnormally.").arg(binary);
+    case StartFailed:
+        return SynchronousProcess::tr("The command '%1' could not be started.").arg(binary);
+    case Hang:
+        return SynchronousProcess::tr("The command '%1' did not respond within the timeout limit (%2 ms).").
+                arg(binary).arg(timeoutMS);
+    }
+    return QString();
+}
+
 QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessResponse& r)
 {
     QDebug nsp = str.nospace();
@@ -120,13 +168,15 @@ struct SynchronousProcessPrivate {
     void clearForRun();
 
     QTextCodec *m_stdOutCodec;
-    QProcess m_process;
+    TerminalControllingProcess m_process;
     QTimer m_timer;
     QEventLoop m_eventLoop;
     SynchronousProcessResponse m_result;
     int m_hangTimerCount;
     int m_maxHangTimerCount;
     bool m_startFailure;
+    bool m_timeOutMessageBoxEnabled;
+    QString m_binary;
 
     ChannelBuffer m_stdOut;
     ChannelBuffer m_stdErr;
@@ -136,7 +186,8 @@ SynchronousProcessPrivate::SynchronousProcessPrivate() :
     m_stdOutCodec(0),
     m_hangTimerCount(0),
     m_maxHangTimerCount(defaultMaxHangTimerCount),
-    m_startFailure(false)
+    m_startFailure(false),
+    m_timeOutMessageBoxEnabled(false)
 {
 }
 
@@ -147,6 +198,7 @@ void SynchronousProcessPrivate::clearForRun()
     m_stdErr.clearForRun();
     m_result.clear();
     m_startFailure = false;
+    m_binary.clear();
 }
 
 // ----------- SynchronousProcess
@@ -217,6 +269,16 @@ QStringList SynchronousProcess::environment() const
     return m_d->m_process.environment();
 }
 
+bool SynchronousProcess::timeOutMessageBoxEnabled() const
+{
+    return m_d->m_timeOutMessageBoxEnabled;
+}
+
+void SynchronousProcess::setTimeOutMessageBoxEnabled(bool v)
+{
+    m_d->m_timeOutMessageBoxEnabled = v;
+}
+
 void SynchronousProcess::setEnvironment(const QStringList &e)
 {
     m_d->m_process.setEnvironment(e);
@@ -232,6 +294,16 @@ QProcessEnvironment SynchronousProcess::processEnvironment() const
     return m_d->m_process.processEnvironment();
 }
 
+unsigned SynchronousProcess::flags() const
+{
+    return m_d->m_process.flags();
+}
+
+void SynchronousProcess::setFlags(unsigned tc)
+{
+    m_d->m_process.setFlags(tc);
+}
+
 void SynchronousProcess::setWorkingDirectory(const QString &workingDirectory)
 {
     m_d->m_process.setWorkingDirectory(workingDirectory);
@@ -263,6 +335,7 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
     // On Windows, start failure is triggered immediately if the
     // executable cannot be found in the path. Do not start the
     // event loop in that case.
+    m_d->m_binary = binary;
     m_d->m_process.start(binary, args, QIODevice::ReadOnly);
     if (!m_d->m_startFailure) {
         m_d->m_timer.start();
@@ -285,13 +358,36 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
     return  m_d->m_result;
 }
 
+static inline bool askToKill(const QString &binary = QString())
+{
+    const QString title = SynchronousProcess::tr("Process not Responding");
+    QString msg = binary.isEmpty() ?
+                  SynchronousProcess::tr("The process is not responding.") :
+                  SynchronousProcess::tr("The process '%1' is not responding.").arg(binary);
+    msg += QLatin1Char(' ');
+    msg += SynchronousProcess::tr(" Would you like to terminate it?");
+    // Restore the cursor that is set to wait while running.
+    const bool hasOverrideCursor = QApplication::overrideCursor() != 0;
+    if (hasOverrideCursor)
+        QApplication::restoreOverrideCursor();
+    QMessageBox::StandardButton answer = QMessageBox::question(0, title, msg, QMessageBox::Yes|QMessageBox::No);
+    if (hasOverrideCursor)
+        QApplication::setOverrideCursor(Qt::WaitCursor);
+    return answer == QMessageBox::Yes;
+}
+
 void SynchronousProcess::slotTimeout()
 {
     if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) {
         if (debug)
             qDebug() << Q_FUNC_INFO << "HANG detected, killing";
-        SynchronousProcess::stopProcess(m_d->m_process);
-        m_d->m_result.result = SynchronousProcessResponse::Hang;
+        const bool terminate = !m_d->m_timeOutMessageBoxEnabled || askToKill(m_d->m_binary);
+        if (terminate) {
+            SynchronousProcess::stopProcess(m_d->m_process);
+            m_d->m_result.result = SynchronousProcessResponse::Hang;
+        } else {
+            m_d->m_hangTimerCount = 0;
+        }
     } else {
         if (debug)
             qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
@@ -401,9 +497,17 @@ void SynchronousProcess::processStdErr(bool emitSignals)
     }
 }
 
+QSharedPointer<QProcess> SynchronousProcess::createProcess(unsigned flags)
+{
+    TerminalControllingProcess *process = new TerminalControllingProcess;
+    process->setFlags(flags);
+    return QSharedPointer<QProcess>(process);
+}
+
 // Static utilities: Keep running as long as it gets data.
 bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeOutMS,
-                                             QByteArray *stdOut, QByteArray *stdErr)
+                                             QByteArray *stdOut, QByteArray *stdErr,
+                                             bool showTimeOutMessageBox)
 {
     if (syncDebug)
         qDebug() << ">readDataFromProcess" << timeOutMS;
@@ -435,6 +539,12 @@ bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeOutMS,
             if (stdErr)
                 stdErr->append(newStdErr);
         }
+        // Prompt user, pretend we have data if says 'No'.
+        const bool hang = !hasData && !finished;
+        if (hang && showTimeOutMessageBox) {
+            if (!askToKill())
+                hasData = true;
+        }
     } while (hasData && !finished);
     if (syncDebug)
         qDebug() << "<readDataFromProcess" << finished;
diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h
index ebe22296180c1d37d554317f8f8f94c2a5920345..102476960e15e1f9406e0784eb3550543c6d80ef 100644
--- a/src/libs/utils/synchronousprocess.h
+++ b/src/libs/utils/synchronousprocess.h
@@ -35,6 +35,7 @@
 #include <QtCore/QObject>
 #include <QtCore/QProcess>
 #include <QtCore/QStringList>
+#include <QtCore/QSharedPointer>
 
 QT_BEGIN_NAMESPACE
 class QTextCodec;
@@ -64,6 +65,9 @@ struct QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
     SynchronousProcessResponse();
     void clear();
 
+    // Helper to format an exit message.
+    QString exitMessage(const QString &binary, int timeoutMS) const;
+
     Result result;
     int exitCode;
     QString stdOut;
@@ -87,12 +91,20 @@ QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessRes
  * There is a timeout handling that takes effect after the last data have been
  * read from stdout/stdin (as opposed to waitForFinished(), which measures time
  * since it was invoked). It is thus also suitable for slow processes that continously
- * output data (like version system operations).  */
+ * output data (like version system operations).
+ *
+ * The property timeOutMessageBoxEnabled influences whether a message box is
+ * shown asking the user if they want to kill the process on timeout (default: false). */
 
 class QTCREATOR_UTILS_EXPORT SynchronousProcess : public QObject
 {
     Q_OBJECT
 public:
+    enum Flags {
+        // Unix: Do not give the child process a terminal for input prompting.
+        UnixTerminalDisabled = 0x1
+    };
+
     SynchronousProcess();
     virtual ~SynchronousProcess();
 
@@ -113,6 +125,9 @@ public:
     bool stdErrBufferedSignalsEnabled() const;
     void setStdErrBufferedSignalsEnabled(bool);
 
+    bool timeOutMessageBoxEnabled() const;
+    void setTimeOutMessageBoxEnabled(bool);
+
     QStringList environment() const;
     void setEnvironment(const QStringList &);
 
@@ -122,14 +137,21 @@ public:
     void setWorkingDirectory(const QString &workingDirectory);
     QString workingDirectory() const;
 
+    unsigned flags() const;
+    void setFlags(unsigned);
+
     SynchronousProcessResponse run(const QString &binary, const QStringList &args);
 
+    // Create a (derived) processes with flags applied.
+    static QSharedPointer<QProcess> createProcess(unsigned flags);
+
     // Static helper for running a process synchronously in the foreground with timeout
     // detection similar SynchronousProcess' handling (taking effect after no more output
     // occurs on stderr/stdout as opposed to waitForFinished()). Returns false if a timeout
     // occurs. Checking of the process' exit state/code still has to be done.
     static bool readDataFromProcess(QProcess &p, int timeOutMS,
-                                    QByteArray *stdOut = 0, QByteArray *stdErr = 0);
+                                    QByteArray *stdOut = 0, QByteArray *stdErr = 0,
+                                    bool timeOutMessageBox = false);
     // Stop a process by first calling terminate() (allowing for signal handling) and
     // then kill().
     static bool stopProcess(QProcess &p);