diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 6b264911cc4..b5e8a3cba8d 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -125,6 +125,9 @@ public: // Used by Valgrind QStringList expectedSignals; + // For QNX debugging + bool useCtrlCStub = false; + // Used by Android to avoid false positives on warnOnRelease bool skipExecutableValidation = false; bool useTargetAsync = false; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 2ff53099e4b..007d3464bb8 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -276,6 +276,11 @@ void DebuggerRunTool::setSkipExecutableValidation(bool on) m_runParameters.skipExecutableValidation = on; } +void DebuggerRunTool::setUseCtrlCStub(bool on) +{ + m_runParameters.useCtrlCStub = on; +} + void DebuggerRunTool::setBreakOnMain(bool on) { m_runParameters.breakOnMain = on; diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index bfd53299a1b..39fb7e9507f 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -100,6 +100,7 @@ protected: void setRemoteChannel(const QUrl &url); void setUseTargetAsync(bool on); void setSkipExecutableValidation(bool on); + void setUseCtrlCStub(bool on); void setIosPlatform(const QString &platform); void setDeviceSymbolsRoot(const QString &deviceSymbolsRoot); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b31ee7130e4..ca10d27d843 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -126,7 +126,6 @@ const char notCompatibleMessage[] = "is not compatible with target architecture" GdbEngine::GdbEngine() { m_gdbProc.setProcessMode(ProcessMode::Writer); - m_gdbProc.setUseCtrlCStub(true); setObjectName("GdbEngine"); setDebuggerName("GDB"); @@ -676,7 +675,26 @@ void GdbEngine::interruptInferior() } else { showStatusMessage(Tr::tr("Stop requested..."), 5000); showMessage("TRYING TO INTERRUPT INFERIOR"); - interruptInferior2(); + if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) { + IDevice::ConstPtr dev = device(); + QTC_ASSERT(dev, notifyInferiorStopFailed(); return); + DeviceProcessSignalOperation::Ptr signalOperation = dev->signalOperation(); + QTC_ASSERT(signalOperation, notifyInferiorStopFailed(); return); + connect(signalOperation.get(), &DeviceProcessSignalOperation::finished, + this, [this, signalOperation](const QString &error) { + if (error.isEmpty()) { + showMessage("Interrupted " + QString::number(inferiorPid())); + notifyInferiorStopOk(); + } else { + showMessage(error, LogError); + notifyInferiorStopFailed(); + } + }); + signalOperation->setDebuggerCommand(runParameters().debugger.command.executable()); + signalOperation->interruptProcess(inferiorPid()); + } else { + interruptInferior2(); + } } } @@ -1249,11 +1267,9 @@ void GdbEngine::handleStopResponse(const GdbMi &data) handleStop1(data); } -static QStringList stopSignals(const Abi &abi) +static QString stopSignal(const Abi &abi) { - static QStringList winSignals = { "SIGTRAP", "SIGINT" }; - static QStringList unixSignals = { "SIGINT" }; - return abi.os() == Abi::WindowsOS ? winSignals : unixSignals; + return QLatin1String(abi.os() == Abi::WindowsOS ? "SIGTRAP" : "SIGINT"); } void GdbEngine::handleStop1(const GdbMi &data) @@ -1402,7 +1418,7 @@ void GdbEngine::handleStop2(const GdbMi &data) QString meaning = data["signal-meaning"].data(); // Ignore these as they are showing up regularly when // stopping debugging. - if (stopSignals(rp.toolChainAbi).contains(name) || rp.expectedSignals.contains(name)) { + if (name == stopSignal(rp.toolChainAbi) || rp.expectedSignals.contains(name)) { showMessage(name + " CONSIDERED HARMLESS. CONTINUING."); } else if (m_isQnxGdb && name == "0" && meaning == "Signal 0") { showMessage("SIGNAL 0 CONSIDERED BOGUS."); @@ -3807,6 +3823,9 @@ void GdbEngine::setupEngine() CHECK_STATE(EngineSetupRequested); showMessage("TRYING TO START ADAPTER"); + if (isRemoteEngine()) + m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX + const DebuggerRunParameters &rp = runParameters(); CommandLine gdbCommand = rp.debugger.command; @@ -4301,6 +4320,7 @@ void GdbEngine::interruptLocalInferior(qint64 pid) showMessage("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED", LogError); return; } + QString errorMessage; if (runParameters().runAsRoot) { Environment env = Environment::systemEnvironment(); RunControl::provideAskPassEntry(env); @@ -4309,8 +4329,11 @@ void GdbEngine::interruptLocalInferior(qint64 pid) proc.setEnvironment(env); proc.start(); proc.waitForFinished(); + } else if (interruptProcess(pid, &errorMessage)) { + showMessage("Interrupted " + QString::number(pid)); } else { - m_gdbProc.interrupt(); + showMessage(errorMessage, LogError); + notifyInferiorStopFailed(); } } diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp index 322c3553071..27c26e269c0 100644 --- a/src/plugins/qnx/qnxdebugsupport.cpp +++ b/src/plugins/qnx/qnxdebugsupport.cpp @@ -126,6 +126,7 @@ public: setStartMode(AttachToRemoteServer); setCloseMode(KillAtClose); + setUseCtrlCStub(true); setSolibSearchPath(FileUtils::toFilePathList(searchPaths(k))); if (auto qtVersion = dynamic_cast(QtSupport::QtKitAspect::qtVersion(k))) { setSysRoot(qtVersion->qnxTarget()); @@ -195,6 +196,7 @@ public: { setId("QnxAttachDebugSupport"); setUsePortsGatherer(isCppDebugging(), isQmlDebugging()); + setUseCtrlCStub(true); if (isCppDebugging()) { auto pdebugRunner = new PDebugRunner(runControl, portsGatherer());