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();
|
notifyInferiorRunOk();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!doInterruptInferior(NoSpecialStop)) {
|
doInterruptInferior(NoSpecialStop);
|
||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorStopFailed")
|
|
||||||
notifyInferiorStopFailed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v)
|
void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v)
|
||||||
@@ -1185,21 +1182,32 @@ void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v)
|
|||||||
m_customSpecialStopData.push_back(v);
|
m_customSpecialStopData.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbEngine::doInterruptInferior(SpecialStopMode sm)
|
void CdbEngine::handleDoInterruptInferior(const QString &errorMessage)
|
||||||
{
|
{
|
||||||
const SpecialStopMode oldSpecialMode = m_specialStopMode;
|
if (errorMessage.isEmpty()) {
|
||||||
m_specialStopMode = sm;
|
showMessage(QLatin1String("Interrupted ") + QString::number(inferiorPid()));
|
||||||
|
} else {
|
||||||
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);
|
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)
|
void CdbEngine::executeRunToLine(const ContextData &data)
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <debugger/debuggerengine.h>
|
#include <debugger/debuggerengine.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
@@ -154,6 +156,8 @@ private slots:
|
|||||||
void consoleStubProcessStarted();
|
void consoleStubProcessStarted();
|
||||||
void consoleStubExited();
|
void consoleStubExited();
|
||||||
|
|
||||||
|
void handleDoInterruptInferior(const QString &errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap;
|
typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap;
|
||||||
typedef QPair<QString, QString> SourcePathMapping;
|
typedef QPair<QString, QString> SourcePathMapping;
|
||||||
@@ -193,7 +197,7 @@ private:
|
|||||||
void handleSessionAccessible(unsigned long cdbExState);
|
void handleSessionAccessible(unsigned long cdbExState);
|
||||||
void handleSessionInaccessible(unsigned long cdbExState);
|
void handleSessionInaccessible(unsigned long cdbExState);
|
||||||
void handleSessionIdle(const QByteArray &message);
|
void handleSessionIdle(const QByteArray &message);
|
||||||
bool doInterruptInferior(SpecialStopMode sm);
|
void doInterruptInferior(SpecialStopMode sm);
|
||||||
void doInterruptInferiorCustomSpecialStop(const QVariant &v);
|
void doInterruptInferiorCustomSpecialStop(const QVariant &v);
|
||||||
void doContinueInferior();
|
void doContinueInferior();
|
||||||
inline void parseOutputLine(QByteArray line);
|
inline void parseOutputLine(QByteArray line);
|
||||||
@@ -254,6 +258,7 @@ private:
|
|||||||
//! Debugger accessible (expecting commands)
|
//! Debugger accessible (expecting commands)
|
||||||
bool m_accessible;
|
bool m_accessible;
|
||||||
SpecialStopMode m_specialStopMode;
|
SpecialStopMode m_specialStopMode;
|
||||||
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||||
int m_nextCommandToken;
|
int m_nextCommandToken;
|
||||||
QList<CdbBuiltinCommandPtr> m_builtinCommandQueue;
|
QList<CdbBuiltinCommandPtr> m_builtinCommandQueue;
|
||||||
int m_currentBuiltinCommandIndex; //!< Current command whose output is recorded.
|
int m_currentBuiltinCommandIndex; //!< Current command whose output is recorded.
|
||||||
|
|||||||
@@ -661,9 +661,9 @@ bool fillParameters(DebuggerStartParameters *sp, const Kit *kit, QString *errorM
|
|||||||
if (tc)
|
if (tc)
|
||||||
sp->toolChainAbi = tc->targetAbi();
|
sp->toolChainAbi = tc->targetAbi();
|
||||||
|
|
||||||
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
|
sp->device = DeviceKitInformation::device(kit);
|
||||||
if (device) {
|
if (sp->device) {
|
||||||
sp->connParams = device->sshParameters();
|
sp->connParams = sp->device->sshParameters();
|
||||||
// Could have been set from command line.
|
// Could have been set from command line.
|
||||||
if (sp->remoteChannel.isEmpty())
|
if (sp->remoteChannel.isEmpty())
|
||||||
sp->remoteChannel = sp->connParams.host + QLatin1Char(':') + QString::number(sp->connParams.port);
|
sp->remoteChannel = sp->connParams.host + QLatin1Char(':') + QString::number(sp->connParams.port);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <projectexplorer/abi.h>
|
#include <projectexplorer/abi.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
|
||||||
@@ -86,6 +87,7 @@ public:
|
|||||||
QString sysRoot;
|
QString sysRoot;
|
||||||
QString debuggerCommand;
|
QString debuggerCommand;
|
||||||
ProjectExplorer::Abi toolChainAbi;
|
ProjectExplorer::Abi toolChainAbi;
|
||||||
|
ProjectExplorer::IDevice::ConstPtr device;
|
||||||
|
|
||||||
QString platform;
|
QString platform;
|
||||||
QString executable;
|
QString executable;
|
||||||
|
|||||||
@@ -65,8 +65,9 @@
|
|||||||
#include <debugger/shared/hostutils.h>
|
#include <debugger/shared/hostutils.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <projectexplorer/taskhub.h>
|
#include <projectexplorer/devicesupport/deviceprocess.h>
|
||||||
#include <projectexplorer/itaskhandler.h>
|
#include <projectexplorer/itaskhandler.h>
|
||||||
|
#include <projectexplorer/taskhub.h>
|
||||||
#include <texteditor/itexteditor.h>
|
#include <texteditor/itexteditor.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -840,9 +841,34 @@ void GdbEngine::interruptInferior()
|
|||||||
} else {
|
} else {
|
||||||
showStatusMessage(tr("Stop requested..."), 5000);
|
showStatusMessage(tr("Stop requested..."), 5000);
|
||||||
showMessage(_("TRYING TO INTERRUPT INFERIOR"));
|
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();
|
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()
|
void GdbEngine::interruptInferiorTemporarily()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
#include <coreplugin/id.h>
|
#include <coreplugin/id.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
@@ -251,6 +253,7 @@ protected: ////////// Gdb Process Management //////////
|
|||||||
void handleAdapterCrashed(const QString &msg);
|
void handleAdapterCrashed(const QString &msg);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void handleInterruptDeviceInferior(const QString &error);
|
||||||
void handleGdbFinished(int, QProcess::ExitStatus status);
|
void handleGdbFinished(int, QProcess::ExitStatus status);
|
||||||
void handleGdbError(QProcess::ProcessError error);
|
void handleGdbError(QProcess::ProcessError error);
|
||||||
void readGdbStandardOutput();
|
void readGdbStandardOutput();
|
||||||
@@ -727,6 +730,7 @@ protected:
|
|||||||
void interruptLocalInferior(qint64 pid);
|
void interruptLocalInferior(qint64 pid);
|
||||||
|
|
||||||
GdbProcess *m_gdbProc;
|
GdbProcess *m_gdbProc;
|
||||||
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,12 @@ void DesktopProcessSignalOperation::killProcessSilently(int pid)
|
|||||||
void DesktopProcessSignalOperation::interruptProcessSilently(int pid)
|
void DesktopProcessSignalOperation::interruptProcessSilently(int pid)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#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
|
Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a
|
||||||
32 bit application inside a 64 bit environment.
|
32 bit application inside a 64 bit environment.
|
||||||
@@ -162,17 +168,17 @@ GDB 32bit | Api | Api | N/A | Win32
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool creatorIs64Bit = Utils::winIs64BitBinary(qApp->applicationFilePath());
|
bool creatorIs64Bit = Utils::winIs64BitBinary(qApp->applicationFilePath());
|
||||||
if (!Utils::winIs64BitSystem() ||
|
if (!is64BitSystem
|
||||||
m_specialInterrupt == NoSpecialInterrupt ||
|
|| si == NoSpecialInterrupt
|
||||||
m_specialInterrupt == Win64Interrupt && creatorIs64Bit ||
|
|| si == Win64Interrupt && creatorIs64Bit
|
||||||
m_specialInterrupt == Win32Interrupt && !creatorIs64Bit) {
|
|| si == Win32Interrupt && !creatorIs64Bit) {
|
||||||
if (!DebugBreakProcess(inferior)) {
|
if (!DebugBreakProcess(inferior)) {
|
||||||
appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed:")
|
appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed:")
|
||||||
+ QLatin1Char(' ') + Utils::winErrorMessage(GetLastError()));
|
+ QLatin1Char(' ') + Utils::winErrorMessage(GetLastError()));
|
||||||
}
|
}
|
||||||
} else if (m_specialInterrupt == Win32Interrupt || m_specialInterrupt == Win64Interrupt) {
|
} else if (si == Win32Interrupt || si == Win64Interrupt) {
|
||||||
QString executable = QCoreApplication::applicationDirPath();
|
QString executable = QCoreApplication::applicationDirPath();
|
||||||
executable += m_specialInterrupt == Win32Interrupt
|
executable += si == Win32Interrupt
|
||||||
? QLatin1String("/win32interrupt.exe")
|
? QLatin1String("/win32interrupt.exe")
|
||||||
: QLatin1String("/win64interrupt.exe");
|
: QLatin1String("/win64interrupt.exe");
|
||||||
if (!QFile::exists(executable)) {
|
if (!QFile::exists(executable)) {
|
||||||
|
|||||||
@@ -426,8 +426,12 @@ QString IDevice::defaultPublicKeyFilePath()
|
|||||||
return defaultPrivateKeyFilePath() + QLatin1String(".pub");
|
return defaultPrivateKeyFilePath() + QLatin1String(".pub");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceProcessSignalOperation::setDebuggerCommand(const QString &cmd)
|
||||||
|
{
|
||||||
|
m_debuggerCommand = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceProcessSignalOperation::DeviceProcessSignalOperation()
|
DeviceProcessSignalOperation::DeviceProcessSignalOperation()
|
||||||
: m_specialInterrupt(NoSpecialInterrupt)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ class PROJECTEXPLORER_EXPORT DeviceProcessSignalOperation : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum SpecialInterrupt { NoSpecialInterrupt, Win32Interrupt, Win64Interrupt };
|
|
||||||
|
|
||||||
~DeviceProcessSignalOperation() {}
|
~DeviceProcessSignalOperation() {}
|
||||||
typedef QSharedPointer<DeviceProcessSignalOperation> Ptr;
|
typedef QSharedPointer<DeviceProcessSignalOperation> Ptr;
|
||||||
|
|
||||||
@@ -69,7 +67,7 @@ public:
|
|||||||
virtual void interruptProcess(int pid) = 0;
|
virtual void interruptProcess(int pid) = 0;
|
||||||
virtual void interruptProcess(const QString &filePath) = 0;
|
virtual void interruptProcess(const QString &filePath) = 0;
|
||||||
|
|
||||||
void setSpecialInterrupt(SpecialInterrupt si);
|
void setDebuggerCommand(const QString &cmd);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// If the error message is empty the operation was successful
|
// If the error message is empty the operation was successful
|
||||||
@@ -77,8 +75,9 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DeviceProcessSignalOperation();
|
explicit DeviceProcessSignalOperation();
|
||||||
|
|
||||||
|
QString m_debuggerCommand;
|
||||||
QString m_errorMessage;
|
QString m_errorMessage;
|
||||||
SpecialInterrupt m_specialInterrupt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT PortsGatheringMethod
|
class PROJECTEXPLORER_EXPORT PortsGatheringMethod
|
||||||
|
|||||||
Reference in New Issue
Block a user