diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp index 706f965998bb5fa9566dca9e1713a67a7dd549f6..9a0464e97eee3ac284e395850dc5ddd3f61d52cf 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp @@ -50,7 +50,7 @@ #include <QtNetwork/QTcpSocket> #ifdef Q_OS_WIN -# include <windows.h> +# include "dbgwinutils.h" #else # include <sys/types.h> # include <unistd.h> @@ -127,7 +127,7 @@ TcfTrkGdbAdapter::TcfTrkGdbAdapter(GdbEngine *engine) : m_gdbConnection = 0; m_snapshot.reset(); #ifdef Q_OS_WIN - const DWORD portOffset = GetCurrentProcessId() % 100; + const unsigned long portOffset = winGetCurrentProcessId() % 100; #else const uid_t portOffset = getuid(); #endif diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index b644d879a95e95e535fd0be27e836562d7cfbb49..1f5b0b97af022abe382194ee1e994514d580cdf6 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -39,12 +39,9 @@ #include <QtGui/QMessageBox> #ifdef Q_OS_WIN -# ifdef __GNUC__ // Required for OpenThread under MinGW -# define _WIN32_WINNT 0x0502 -# endif // __GNUC__ -# include <windows.h> -# include <utils/winutils.h> -#endif // Q_OS_WIN +# include "dbgwinutils.h" +# include "dbgwinutils.h" +#endif namespace Debugger { namespace Internal { @@ -138,42 +135,23 @@ void TermGdbAdapter::setupInferior() CB(handleStubAttached)); } -#ifdef Q_OS_WIN -static bool resumeThread(DWORD dwThreadId) -{ - bool ok = false; - HANDLE handle = NULL; - do { - if (!dwThreadId) - break; - - handle = OpenThread(SYNCHRONIZE |THREAD_QUERY_INFORMATION |THREAD_SUSPEND_RESUME, - FALSE, dwThreadId); - if (handle==NULL) - break; - - ok = ResumeThread(handle) != DWORD(-1); - } while (false); - if (handle != NULL) - CloseHandle(handle); - return ok; -} -#endif // Q_OS_WIN - void TermGdbAdapter::handleStubAttached(const GdbResponse &response) { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); +#ifdef Q_OS_WIN + QString errorMessage; +#endif // Q_OS_WIN switch (response.resultClass) { case GdbResultDone: case GdbResultRunning: #ifdef Q_OS_WIN // Resume thread that was suspended by console stub process (see stub code). - if (resumeThread(m_stubProc.applicationMainThreadID())) { + if (winResumeThread(m_stubProc.applicationMainThreadID(), &errorMessage)) { showMessage(QString::fromLatin1("Inferior attached, thread %1 resumed"). arg(m_stubProc.applicationMainThreadID()), LogMisc); } else { showMessage(QString::fromLatin1("Inferior attached, unable to resume thread %1: %2"). - arg(m_stubProc.applicationMainThreadID()).arg(Utils::winErrorMessage(GetLastError())), + arg(m_stubProc.applicationMainThreadID()).arg(errorMessage), LogWarning); } #else diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index fa2d30cdaaf30852e60e5c5fd383058eeecd6331..e5169d77019ae1579493f42a767e17d093d489f3 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -52,7 +52,7 @@ #include <QtNetwork/QTcpSocket> #ifdef Q_OS_WIN -# include <windows.h> +# include "dbgwinutils.h" #else # include <sys/types.h> # include <unistd.h> @@ -100,7 +100,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine) : m_gdbConnection = 0; m_snapshot.reset(); #ifdef Q_OS_WIN - const DWORD portOffset = GetCurrentProcessId() % 100; + const unsigned long portOffset = winGetCurrentProcessId() % 100; #else const uid_t portOffset = getuid(); #endif diff --git a/src/plugins/debugger/shared/dbgwinutils.cpp b/src/plugins/debugger/shared/dbgwinutils.cpp index d669665305b718994bd35dde90d17219e7a12ec1..c2ed55d5078a8fb8b612dc7b6753fb3f6ef92c3a 100644 --- a/src/plugins/debugger/shared/dbgwinutils.cpp +++ b/src/plugins/debugger/shared/dbgwinutils.cpp @@ -31,8 +31,19 @@ #include "debuggerdialogs.h" #include <QtCore/QDebug> +#include <QtCore/QString> + +#ifdef Q_OS_WIN +# ifdef __GNUC__ // Required for OpenThread under MinGW +# define _WIN32_WINNT 0x0502 +# endif // __GNUC__ +# include <windows.h> +# include <utils/winutils.h> +# if !defined(PROCESS_SUSPEND_RESUME) // Check flag for MinGW +# define PROCESS_SUSPEND_RESUME (0x0800) +# endif // PROCESS_SUSPEND_RESUME +#endif // Q_OS_WIN -#include <windows.h> #include <tlhelp32.h> #include <psapi.h> #include <QtCore/QLibrary> @@ -98,5 +109,63 @@ QList<ProcData> winProcessList() return rc; } +bool winResumeThread(unsigned long dwThreadId, QString *errorMessage) +{ + bool ok = false; + HANDLE handle = NULL; + do { + if (!dwThreadId) + break; + + handle = OpenThread(SYNCHRONIZE |THREAD_QUERY_INFORMATION |THREAD_SUSPEND_RESUME, + FALSE, dwThreadId); + if (handle==NULL) { + *errorMessage = QString::fromLatin1("Unable to open thread %1: %2"). + arg(dwThreadId).arg(Utils::winErrorMessage(GetLastError())); + break; + } + if (ResumeThread(handle) == DWORD(-1)) { + *errorMessage = QString::fromLatin1("Unable to resume thread %1: %2"). + arg(dwThreadId).arg(Utils::winErrorMessage(GetLastError())); + break; + } + ok = true; + } while (false); + if (handle != NULL) + CloseHandle(handle); + return ok; +} + +// Open the process and break into it +bool winDebugBreakProcess(unsigned long pid, QString *errorMessage) +{ + bool ok = false; + HANDLE inferior = NULL; + do { + const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION + |PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ + |PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME ; + inferior = OpenProcess(rights, FALSE, pid); + if (inferior == NULL) { + *errorMessage = QString::fromLatin1("Cannot open process %1: %2"). + arg(pid).arg(Utils::winErrorMessage(GetLastError())); + break; + } + if (!DebugBreakProcess(inferior)) { + *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError())); + break; + } + ok = true; + } while (false); + if (inferior != NULL) + CloseHandle(inferior); + return ok; +} + +unsigned long winGetCurrentProcessId() +{ + return GetCurrentProcessId(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/shared/dbgwinutils.h b/src/plugins/debugger/shared/dbgwinutils.h index 035933884ae6ccca88f72ba93fa8472dbe4a24ca..10d94c722bc2b0f746575fa8b6133cefd6507605 100644 --- a/src/plugins/debugger/shared/dbgwinutils.h +++ b/src/plugins/debugger/shared/dbgwinutils.h @@ -32,6 +32,8 @@ #include <QtCore/QList> +QT_FORWARD_DECLARE_CLASS(QString) + namespace Debugger { namespace Internal { @@ -39,6 +41,14 @@ struct ProcData; // debuggerdialogs, used by the process listing dialogs QList<ProcData> winProcessList(); +// Resume a suspended thread by id. +bool winResumeThread(unsigned long dwThreadId, QString *errorMessage); + +// Open a process by PID and break into it. +bool winDebugBreakProcess(unsigned long pid, QString *errorMessage); + +unsigned long winGetCurrentProcessId(); + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/projectexplorer/debugginghelper.cpp b/src/plugins/projectexplorer/debugginghelper.cpp index ed6429cbefc9536a0d1da881ac46b2ec99ca5679..235262577d7c1ceaff0cb4ed8b784c9f4819e5a0 100644 --- a/src/plugins/projectexplorer/debugginghelper.cpp +++ b/src/plugins/projectexplorer/debugginghelper.cpp @@ -258,6 +258,10 @@ QString DebuggingHelperLibrary::qtVersionForQMake(const QString &qmakePath) qWarning("Timeout running '%s'.", qPrintable(qmakePath)); return QString(); } + if (qmake.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(qmakePath)); + return QString(); + } const QString output = QString::fromLocal8Bit(qmake.readAllStandardOutput()); QRegExp regexp(QLatin1String("(QMake version|QMake version:)[\\s]*([\\d.]*)"), Qt::CaseInsensitive); regexp.indexIn(output); diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 0a3ec26c261f5eda237d1be8b3be48c2d1e43c37..9674d0972a1172dc543c1e39ac72f0f2573f61ff 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -514,20 +514,6 @@ public: TaskHub *m_taskHub; }; -static QToolButton *createFilterButton(QIcon icon, const QString &toolTip, - QObject *receiver, const char *slot) -{ - QToolButton *button = new QToolButton; - button->setIcon(icon); - button->setToolTip(toolTip); - button->setCheckable(true); - button->setChecked(true); - button->setAutoRaise(true); - button->setEnabled(true); - QObject::connect(button, SIGNAL(toggled(bool)), receiver, slot); - return button; -} - TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate) { d->m_defaultHandler = 0; diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index fac8f256c590f3857618947e91df66a8a2a4d001..e59900f9a3f1ef745cf17c72a7452cdf165d455d 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -199,7 +199,10 @@ static QByteArray gccPredefinedMacros(const QString &gcc, const QStringList &env qWarning("Timeout running '%s'.", qPrintable(gcc)); return QByteArray(); } - + if (cpp.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(gcc)); + return QByteArray(); + } QByteArray predefinedMacros = cpp.readAllStandardOutput(); #ifdef Q_OS_MAC // Turn off flag indicating Apple's blocks support @@ -251,7 +254,10 @@ static QList<HeaderPath> gccSystemHeaderPaths(const QString &gcc, ProjectExplore qWarning("Timeout running '%s'.", qPrintable(gcc)); return systemHeaderPaths; } - + if (cpp.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(gcc)); + return systemHeaderPaths; + } QByteArray line; while (cpp.canReadLine()) { line = cpp.readLine(); @@ -659,6 +665,11 @@ static QByteArray msvcPredefinedMacros(const QStringList &env) qWarning("Timeout running '%s'.", qPrintable(binary)); return predefinedMacros; } + if (cpp.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(binary)); + return predefinedMacros; + } + const QList<QByteArray> output = cpp.readAllStandardOutput().split('\n'); foreach (const QByteArray& line, output) { if (line.startsWith('V')) { diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp index 389d1367934454b3ed50c0af41917f1124fbc829..5d8d32545c9b1f62244ce2dbde85e5cf680d1551 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp @@ -452,8 +452,7 @@ void MaemoDeployStep::setupMount() } else { #ifdef Q_OS_WIN bool drivesToMount[26]; - for (int i = 0; i < sizeof drivesToMount / sizeof drivesToMount[0]; ++i) - drivesToMount[i] = false; + qFill(drivesToMount, drivesToMount + sizeof drivesToMount / sizeof drivesToMount[0], false); for (int i = 0; i < m_filesToCopy.count(); ++i) { const QString localDir = QFileInfo(m_filesToCopy.at(i).localFilePath).canonicalPath(); diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp index d5128e2db0680c84ed1889b3310a051a0376ae46..d5acadb48cd3da579c05416312b1666fb97e25a8 100644 --- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp @@ -31,6 +31,7 @@ #include "qt4project.h" #include <utils/qtcassert.h> +#include <utils/synchronousprocess.h> #include <QtCore/QDir> #include <QtCore/QProcess> @@ -173,14 +174,23 @@ QString GCCEToolChain::gcceVersion() const gxx.setEnvironment(env.toStringList()); gxx.setReadChannelMode(QProcess::MergedChannels); gxx.start(command, arguments); + if (!gxx.waitForStarted()) { + qWarning("Cannot start '%s': %s", qPrintable(command), qPrintable(gxx.errorString())); + return QString(); + } gxx.closeWriteChannel(); - gxx.waitForFinished(); - - QString line; - if (gxx.canReadLine()) { - line = gxx.readLine(); - m_gcceVersion = line.trimmed(); + if (!gxx.waitForFinished()) { + Utils::SynchronousProcess::stopProcess(gxx); + qWarning("Timeout running '%s'.", qPrintable(command)); + return QString(); } + if (gxx.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(command)); + return QString(); + } + + if (gxx.canReadLine()) + m_gcceVersion = gxx.readLine().trimmed(); } return m_gcceVersion; } diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp index dd778dd2864386f9cd82556daaef2e4e29ed8e08..e2ca351419d276f1482d6fe5833f9a7ddfc67f28 100644 --- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp @@ -31,6 +31,7 @@ #include "rvctparser.h" #include <utils/qtcassert.h> +#include <utils/synchronousprocess.h> #include <QtCore/QProcess> #include <QtCore/QProcessEnvironment> @@ -126,7 +127,15 @@ void RVCTToolChain::updateVersion() return; } armcc.closeWriteChannel(); - armcc.waitForFinished(); + if (!armcc.waitForFinished()) { + Utils::SynchronousProcess::stopProcess(armcc); + qWarning("Timeout running rvct binary '%s' trying to determine version.", qPrintable(binary)); + return; + } + if (armcc.exitStatus() != QProcess::NormalExit) { + qWarning("A crash occurred when running rvct binary '%s' trying to determine version.", qPrintable(binary)); + return; + } QString versionLine = QString::fromLocal8Bit(armcc.readAllStandardOutput()); versionLine += QString::fromLocal8Bit(armcc.readAllStandardError()); const QRegExp versionRegExp(QLatin1String("RVCT(\\d*)\\.(\\d*).*\\[Build.(\\d*)\\]"), diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 99655f546e62fbd0a4429f30e9efc576f8af95d1..c7381b527a822fc6001674e85281b63c11841a0b 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -1096,6 +1096,10 @@ static bool queryQMakeVariables(const QString &binary, QHash<QString, QString> * qWarning("Timeout running '%s' (%dms).", qPrintable(binary), timeOutMS); return false; } + if (process.exitStatus() != QProcess::NormalExit) { + qWarning("'%s' crashed.", qPrintable(binary)); + return false; + } QByteArray output = process.readAllStandardOutput(); QTextStream stream(&output); while (!stream.atEnd()) {