Commit 94c10ae6 authored by David Schulz's avatar David Schulz Committed by hjk

Debugger: Interrupt inferior via signal operation on Windows.

Task-number: QTCREATORBUG-10558

Change-Id: I5a27beca4601cae3b0de8f903a2cbc08ee801149
Reviewed-by: default avatarRobert Loehning <robert.loehning@digia.com>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 9a4caa4b
......@@ -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)
......
......@@ -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"));
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()
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment