forked from qt-creator/qt-creator
Debugger: Interrupt inferior via signal operation on Windows.
Task-number: QTCREATORBUG-10558 Change-Id: I5a27beca4601cae3b0de8f903a2cbc08ee801149 Reviewed-by: Robert Loehning <robert.loehning@digia.com> Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
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;
|
||||
if (errorMessage.isEmpty()) {
|
||||
showMessage(QLatin1String("Interrupted ") + QString::number(inferiorPid()));
|
||||
} else {
|
||||
showMessage(errorMessage, LogError);
|
||||
notifyInferiorStopFailed();
|
||||
}
|
||||
return ok;
|
||||
m_signalOperation->disconnect(this);
|
||||
m_signalOperation.clear();
|
||||
}
|
||||
|
||||
void CdbEngine::doInterruptInferior(SpecialStopMode sm)
|
||||
{
|
||||
showMessage(QString::fromLatin1("Interrupting process %1...").arg(inferiorPid()), LogMisc);
|
||||
|
||||
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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
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()
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user