diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 8bfe007359afc87dfc877b48bc5b330807b03e12..00cf0137cfd82d4ea3e6966bfdfca22862f6f871 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1172,10 +1172,7 @@ void CdbEngine::interruptInferior() notifyInferiorRunOk(); return; } - if (!doInterruptInferior(NoSpecialStop)) { - STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorStopFailed") - notifyInferiorStopFailed(); - } + doInterruptInferior(NoSpecialStop); } void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v) @@ -1185,21 +1182,32 @@ void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v) m_customSpecialStopData.push_back(v); } -bool CdbEngine::doInterruptInferior(SpecialStopMode sm) +void CdbEngine::handleDoInterruptInferior(const QString &errorMessage) { - const SpecialStopMode oldSpecialMode = m_specialStopMode; - m_specialStopMode = sm; + if (errorMessage.isEmpty()) { + showMessage(QLatin1String("Interrupted ") + QString::number(inferiorPid())); + } else { + showMessage(errorMessage, LogError); + notifyInferiorStopFailed(); + } + m_signalOperation->disconnect(this); + m_signalOperation.clear(); +} +void CdbEngine::doInterruptInferior(SpecialStopMode sm) +{ showMessage(QString::fromLatin1("Interrupting process %1...").arg(inferiorPid()), LogMisc); - QString errorMessage; - const bool ok = interruptProcess(inferiorPid(), CdbEngineType, - &errorMessage, m_cdbIs64Bit); - if (!ok) { - m_specialStopMode = oldSpecialMode; - showMessage(errorMessage, LogError); - } - return ok; + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); notifyInferiorStopFailed(); return;); + QTC_ASSERT(!m_signalOperation, notifyInferiorStopFailed(); return;); + m_signalOperation = startParameters().device->signalOperation(); + m_specialStopMode = sm; + QTC_ASSERT(m_signalOperation, notifyInferiorStopFailed(); return;); + connect(m_signalOperation.data(), SIGNAL(finished(QString)), + SLOT(handleDoInterruptInferior(QString))); + + m_signalOperation->setDebuggerCommand(startParameters().debuggerCommand); + m_signalOperation->interruptProcess(inferiorPid()); } void CdbEngine::executeRunToLine(const ContextData &data) diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 097407c3f8ced8e0c9c533e3c0a65b3a2a90fb77..4d8e9d1214606ae66e185100325da616b8fcd81d 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -32,6 +32,8 @@ #include <debugger/debuggerengine.h> +#include <projectexplorer/devicesupport/idevice.h> + #include <QSharedPointer> #include <QProcess> #include <QMap> @@ -154,6 +156,8 @@ private slots: void consoleStubProcessStarted(); void consoleStubExited(); + void handleDoInterruptInferior(const QString &errorMessage); + private: typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap; typedef QPair<QString, QString> SourcePathMapping; @@ -193,7 +197,7 @@ private: void handleSessionAccessible(unsigned long cdbExState); void handleSessionInaccessible(unsigned long cdbExState); void handleSessionIdle(const QByteArray &message); - bool doInterruptInferior(SpecialStopMode sm); + void doInterruptInferior(SpecialStopMode sm); void doInterruptInferiorCustomSpecialStop(const QVariant &v); void doContinueInferior(); inline void parseOutputLine(QByteArray line); @@ -254,6 +258,7 @@ private: //! Debugger accessible (expecting commands) bool m_accessible; SpecialStopMode m_specialStopMode; + ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation; int m_nextCommandToken; QList<CdbBuiltinCommandPtr> m_builtinCommandQueue; int m_currentBuiltinCommandIndex; //!< Current command whose output is recorded. diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index cc42f45a3f730b58a9593761d85282dd0f697826..5495ceb0cd822b1297bb54394113a72f94f3304e 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -661,9 +661,9 @@ bool fillParameters(DebuggerStartParameters *sp, const Kit *kit, QString *errorM if (tc) sp->toolChainAbi = tc->targetAbi(); - IDevice::ConstPtr device = DeviceKitInformation::device(kit); - if (device) { - sp->connParams = device->sshParameters(); + sp->device = DeviceKitInformation::device(kit); + if (sp->device) { + sp->connParams = sp->device->sshParameters(); // Could have been set from command line. if (sp->remoteChannel.isEmpty()) sp->remoteChannel = sp->connParams.host + QLatin1Char(':') + QString::number(sp->connParams.port); diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index 3443152039a1442d6448d10b0a0d7e0207fc76ad..2b46a94b93b11a33b0abd7a305a53241ef7f961b 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -38,6 +38,7 @@ #include <utils/environment.h> #include <projectexplorer/abi.h> #include <projectexplorer/kit.h> +#include <projectexplorer/devicesupport/idevice.h> #include <QMetaType> @@ -86,6 +87,7 @@ public: QString sysRoot; QString debuggerCommand; ProjectExplorer::Abi toolChainAbi; + ProjectExplorer::IDevice::ConstPtr device; QString platform; QString executable; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 77ec8991a2eba846fafe1af5a5c4e601eadf0f70..00f98ee4f4b51961d9898bef1978d32e42742c83 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -65,8 +65,9 @@ #include <debugger/shared/hostutils.h> #include <coreplugin/icore.h> -#include <projectexplorer/taskhub.h> +#include <projectexplorer/devicesupport/deviceprocess.h> #include <projectexplorer/itaskhandler.h> +#include <projectexplorer/taskhub.h> #include <texteditor/itexteditor.h> #include <utils/hostosinfo.h> #include <utils/qtcassert.h> @@ -840,8 +841,33 @@ void GdbEngine::interruptInferior() } else { showStatusMessage(tr("Stop requested..."), 5000); showMessage(_("TRYING TO INTERRUPT INFERIOR")); - interruptInferior2(); + if (Utils::HostOsInfo::isWindowsHost() && !m_isQnxGdb) { + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); notifyInferiorStopFailed()); + QTC_ASSERT(!m_signalOperation, notifyInferiorStopFailed()); + m_signalOperation = startParameters().device->signalOperation(); + QTC_ASSERT(m_signalOperation, notifyInferiorStopFailed()); + connect(m_signalOperation.data(), SIGNAL(finished(QString)), + SLOT(handleInterruptDeviceInferior(QString))); + + m_signalOperation->setDebuggerCommand(startParameters().debuggerCommand); + m_signalOperation->interruptProcess(inferiorPid()); + } else { + interruptInferior2(); + } + } +} + +void GdbEngine::handleInterruptDeviceInferior(const QString &error) +{ + if (error.isEmpty()) { + showMessage(QLatin1String("Interrupted ") + QString::number(inferiorPid())); + notifyInferiorStopOk(); + } else { + showMessage(error, LogError); + notifyInferiorStopFailed(); } + m_signalOperation->disconnect(this); + m_signalOperation.clear(); } void GdbEngine::interruptInferiorTemporarily() diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 592be2b0a986e0ee0ae976b747466c9d9f2b526e..6a60457cf2b7a10eaa9e8e114cc9227faf8c448d 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -37,6 +37,8 @@ #include <coreplugin/id.h> +#include <projectexplorer/devicesupport/idevice.h> + #include <QProcess> #include <QTextCodec> #include <QTime> @@ -251,6 +253,7 @@ protected: ////////// Gdb Process Management ////////// void handleAdapterCrashed(const QString &msg); private slots: + void handleInterruptDeviceInferior(const QString &error); void handleGdbFinished(int, QProcess::ExitStatus status); void handleGdbError(QProcess::ProcessError error); void readGdbStandardOutput(); @@ -727,6 +730,7 @@ protected: void interruptLocalInferior(qint64 pid); GdbProcess *m_gdbProc; + ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation; }; diff --git a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp index 7fce79f8e994e9a9da114cfa1504fb3553400743..fa6c39a271c5a479e81008a97237dfb16598da01 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp @@ -121,6 +121,12 @@ void DesktopProcessSignalOperation::killProcessSilently(int pid) void DesktopProcessSignalOperation::interruptProcessSilently(int pid) { #ifdef Q_OS_WIN + enum SpecialInterrupt { NoSpecialInterrupt, Win32Interrupt, Win64Interrupt }; + + bool is64BitSystem = Utils::winIs64BitSystem(); + SpecialInterrupt si = NoSpecialInterrupt; + if (is64BitSystem) + si = Utils::winIs64BitBinary(m_debuggerCommand) ? Win64Interrupt : Win32Interrupt; /* Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a 32 bit application inside a 64 bit environment. @@ -162,17 +168,17 @@ GDB 32bit | Api | Api | N/A | Win32 break; } bool creatorIs64Bit = Utils::winIs64BitBinary(qApp->applicationFilePath()); - if (!Utils::winIs64BitSystem() || - m_specialInterrupt == NoSpecialInterrupt || - m_specialInterrupt == Win64Interrupt && creatorIs64Bit || - m_specialInterrupt == Win32Interrupt && !creatorIs64Bit) { + if (!is64BitSystem + || si == NoSpecialInterrupt + || si == Win64Interrupt && creatorIs64Bit + || si == Win32Interrupt && !creatorIs64Bit) { if (!DebugBreakProcess(inferior)) { appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed:") + QLatin1Char(' ') + Utils::winErrorMessage(GetLastError())); } - } else if (m_specialInterrupt == Win32Interrupt || m_specialInterrupt == Win64Interrupt) { + } else if (si == Win32Interrupt || si == Win64Interrupt) { QString executable = QCoreApplication::applicationDirPath(); - executable += m_specialInterrupt == Win32Interrupt + executable += si == Win32Interrupt ? QLatin1String("/win32interrupt.exe") : QLatin1String("/win64interrupt.exe"); if (!QFile::exists(executable)) { diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 88b135a59e31e9b9c185233f1f1ec5db969b8892..42a67dac324e39121228744f1d26857643547623 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -426,8 +426,12 @@ QString IDevice::defaultPublicKeyFilePath() return defaultPrivateKeyFilePath() + QLatin1String(".pub"); } +void DeviceProcessSignalOperation::setDebuggerCommand(const QString &cmd) +{ + m_debuggerCommand = cmd; +} + DeviceProcessSignalOperation::DeviceProcessSignalOperation() - : m_specialInterrupt(NoSpecialInterrupt) { } diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index a0e021fc2ae0321697715117cdc164c621118c2a..2583ab1c984692ac45e1d7791645e55b112b6713 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -59,8 +59,6 @@ class PROJECTEXPLORER_EXPORT DeviceProcessSignalOperation : public QObject { Q_OBJECT public: - enum SpecialInterrupt { NoSpecialInterrupt, Win32Interrupt, Win64Interrupt }; - ~DeviceProcessSignalOperation() {} typedef QSharedPointer<DeviceProcessSignalOperation> Ptr; @@ -69,7 +67,7 @@ public: virtual void interruptProcess(int pid) = 0; virtual void interruptProcess(const QString &filePath) = 0; - void setSpecialInterrupt(SpecialInterrupt si); + void setDebuggerCommand(const QString &cmd); signals: // If the error message is empty the operation was successful @@ -77,8 +75,9 @@ signals: protected: explicit DeviceProcessSignalOperation(); + + QString m_debuggerCommand; QString m_errorMessage; - SpecialInterrupt m_specialInterrupt; }; class PROJECTEXPLORER_EXPORT PortsGatheringMethod