diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index ca5f2030329..00100592c5b 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -27,7 +27,6 @@ #include "sourceutils.h" #include "stackhandler.h" #include "stackwindow.h" -#include "terminal.h" #include "threadshandler.h" #include "watchhandler.h" #include "watchutils.h" @@ -451,7 +450,6 @@ public: // The current state. DebuggerState m_state = DebuggerNotReady; -// Terminal m_terminal; ProcessHandle m_inferiorPid; BreakHandler m_breakHandler; @@ -531,7 +529,7 @@ public: OptionalAction m_operateInReverseDirectionAction{Tr::tr("Reverse Direction")}; OptionalAction m_snapshotAction{Tr::tr("Take Snapshot of Process State")}; - QPointer m_terminalRunner; + QPointer m_runTool; DebuggerToolTipManager m_toolTipManager; Context m_context; }; @@ -1075,10 +1073,9 @@ void DebuggerEngine::setRunId(const QString &id) void DebuggerEngine::setRunTool(DebuggerRunTool *runTool) { + d->m_runTool = runTool; d->m_device = runTool->device(); - d->m_terminalRunner = runTool->terminalRunner(); - validateRunParameters(d->m_runParameters); d->setupViews(); @@ -2089,27 +2086,31 @@ void DebuggerEngine::setSecondaryEngine() bool DebuggerEngine::usesTerminal() const { - return bool(d->m_terminalRunner); + return d->m_runParameters.useTerminal; } qint64 DebuggerEngine::applicationPid() const { - return d->m_terminalRunner->applicationPid(); + QTC_CHECK(usesTerminal()); + return d->m_runParameters.applicationPid; } qint64 DebuggerEngine::applicationMainThreadId() const { - return d->m_terminalRunner->applicationMainThreadId(); + QTC_CHECK(usesTerminal()); + return d->m_runParameters.applicationMainThreadId; } void DebuggerEngine::interruptTerminal() const { - d->m_terminalRunner->interrupt(); + QTC_ASSERT(usesTerminal(), return); + d->m_runTool->interruptTerminal(); } void DebuggerEngine::kickoffTerminalProcess() const { - d->m_terminalRunner->kickoffProcess(); + QTC_ASSERT(usesTerminal(), return); + d->m_runTool->kickoffTerminalProcess(); } void DebuggerEngine::selectWatchData(const QString &) diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 3dd5a890324..15a8ca8ddc5 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -166,6 +166,10 @@ public: Utils::FilePath projectSourceDirectory; Utils::FilePaths projectSourceFiles; + // Terminal + qint64 applicationPid = 0; + qint64 applicationMainThreadId = 0; + // Used by Script debugging Utils::FilePath interpreter; Utils::FilePath mainScript; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 075447efccf..154e30e4fc4 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -5,7 +5,6 @@ #include "debuggermainwindow.h" #include "debuggertr.h" -#include "terminal.h" #include "console/console.h" #include "debuggeractions.h" @@ -156,15 +155,15 @@ private: class DebuggerRunToolPrivate { public: - bool useTerminal = false; QPointer coreUnpacker; QPointer portsGatherer; bool addQmlServerInferiorCommandLineArgumentIfNeeded = false; - TerminalRunner *terminalRunner = nullptr; int snapshotCounter = 0; int engineStartsNeeded = 0; int engineStopsNeeded = 0; QString runId; + Process terminalProc; + DebuggerRunTool::AllowTerminal allowTerminal = DebuggerRunTool::DoAllowTerminal; }; } // namespace Internal @@ -288,20 +287,7 @@ void DebuggerRunTool::setBreakOnMain(bool on) void DebuggerRunTool::setUseTerminal(bool on) { - // CDB has a built-in console that might be preferred by some. - bool useCdbConsole = m_runParameters.cppEngineType == CdbEngineType - && (m_runParameters.startMode == StartInternal - || m_runParameters.startMode == StartExternal) - && settings().useCdbConsole(); - - if (on && !d->terminalRunner && !useCdbConsole) { - d->terminalRunner = - new TerminalRunner(runControl(), [this] { return m_runParameters.inferior; }); - addStartDependency(d->terminalRunner); - } - if (!on && d->terminalRunner) { - QTC_CHECK(false); // User code can only switch from no terminal to one terminal. - } + m_runParameters.useTerminal = on; } void DebuggerRunTool::setCommandsAfterConnect(const QString &commands) @@ -415,6 +401,56 @@ void DebuggerRunTool::addSearchDirectory(const Utils::FilePath &dir) } void DebuggerRunTool::start() +{ + startTerminalIfNeededAndContinueStartup(); +} + +void DebuggerRunTool::startTerminalIfNeededAndContinueStartup() +{ + if (d->allowTerminal == DoNotAllowTerminal) + m_runParameters.useTerminal = false; + + // CDB has a built-in console that might be preferred by some. + const bool useCdbConsole = m_runParameters.cppEngineType == CdbEngineType + && (m_runParameters.startMode == StartInternal + || m_runParameters.startMode == StartExternal) + && settings().useCdbConsole(); + if (useCdbConsole) + m_runParameters.useTerminal = false; + + if (!m_runParameters.useTerminal) { + continueAfterTerminalStart(); + return; + } + + // Actually start the terminal. + ProcessRunData stub = m_runParameters.inferior; + + if (m_runParameters.runAsRoot) { + d->terminalProc.setRunAsRoot(true); + RunControl::provideAskPassEntry(stub.environment); + } + + d->terminalProc.setTerminalMode(TerminalMode::Debug); + d->terminalProc.setRunData(stub); + + connect(&d->terminalProc, &Process::started, this, [this] { + m_runParameters.applicationPid = d->terminalProc.processId(); + m_runParameters.applicationMainThreadId = d->terminalProc.applicationMainThreadId(); + continueAfterTerminalStart(); + }); + + connect(&d->terminalProc, &Process::done, this, [this] { + if (d->terminalProc.error() != QProcess::UnknownError) + reportFailure(d->terminalProc.errorString()); + if (d->terminalProc.error() != QProcess::FailedToStart) + reportDone(); + }); + + d->terminalProc.start(); +} + +void DebuggerRunTool::continueAfterTerminalStart() { TaskHub::clearTasks(Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); @@ -648,6 +684,16 @@ void DebuggerRunTool::start() Utils::reverseForeach(m_engines, [](DebuggerEngine *engine) { engine->start(); }); } +void DebuggerRunTool::kickoffTerminalProcess() +{ + d->terminalProc.kickoffProcess(); +} + +void DebuggerRunTool::interruptTerminal() +{ + d->terminalProc.interrupt(); +} + void DebuggerRunTool::stop() { QTC_ASSERT(!m_engines.isEmpty(), reportStopped(); return); @@ -810,11 +856,6 @@ bool DebuggerRunTool::fixupParameters() return true; } -Internal::TerminalRunner *DebuggerRunTool::terminalRunner() const -{ - return d->terminalRunner; -} - DebuggerEngineType DebuggerRunTool::cppEngineType() const { return m_runParameters.cppEngineType; @@ -832,6 +873,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm toolRunCount = 0; d->runId = QString::number(++toolRunCount); + d->allowTerminal = allowTerminal; runControl->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL_TOOLBAR); runControl->setPromptToStop([](bool *optionalPrompt) { @@ -891,8 +933,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm inferior.workingDirectory = inferior.workingDirectory.normalizedPathName(); m_runParameters.inferior = inferior; - setUseTerminal(allowTerminal == DoAllowTerminal && m_runParameters.useTerminal); - const QString envBinary = qtcEnvironmentVariable("QTC_DEBUGGER_PATH"); if (!envBinary.isEmpty()) m_runParameters.debugger.command.setExecutable(FilePath::fromString(envBinary)); diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 39fb7e9507f..beadec4b102 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -6,7 +6,6 @@ #include "debugger_global.h" #include "debuggerconstants.h" #include "debuggerengine.h" -#include "terminal.h" #include #include @@ -16,10 +15,7 @@ namespace Debugger { -namespace Internal { -class TerminalRunner; -class DebuggerRunToolPrivate; -} // Internal +namespace Internal { class DebuggerRunToolPrivate; } class DebugServerPortsGatherer; @@ -80,7 +76,8 @@ public: void setTestCase(int testCase); void setOverrideStartScript(const Utils::FilePath &script); - Internal::TerminalRunner *terminalRunner() const; + void kickoffTerminalProcess(); + void interruptTerminal(); Internal::DebuggerRunParameters &runParameters() { return m_runParameters; } @@ -115,6 +112,9 @@ private: void handleEngineStarted(Internal::DebuggerEngine *engine); void handleEngineFinished(Internal::DebuggerEngine *engine); + void startTerminalIfNeededAndContinueStartup(); + void continueAfterTerminalStart(); + Internal::DebuggerRunToolPrivate *d; QList> m_engines; Internal::DebuggerRunParameters m_runParameters; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b9f3eade80e..d1e65f3ed18 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index 3ca2b004c20..78f2589a776 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -149,76 +149,5 @@ void Terminal::onSlaveReaderActivated(int fd) #endif } -TerminalRunner::TerminalRunner(RunControl *runControl, - const std::function &stubRunnable) - : RunWorker(runControl), m_stubRunnable(stubRunnable) -{ - setId("TerminalRunner"); -} - -void TerminalRunner::kickoffProcess() -{ - if (m_stubProc) - m_stubProc->kickoffProcess(); -} - -void TerminalRunner::interrupt() -{ - if (m_stubProc) - m_stubProc->interrupt(); -} - -void TerminalRunner::start() -{ - QTC_ASSERT(m_stubRunnable, reportFailure({}); return); - QTC_ASSERT(!m_stubProc, reportFailure({}); return); - ProcessRunData stub = m_stubRunnable(); - - bool runAsRoot = false; - if (auto runAsRootAspect = runControl()->aspectData()) - runAsRoot = runAsRootAspect->value; - - m_stubProc = new Process(this); - m_stubProc->setTerminalMode(TerminalMode::Debug); - - if (runAsRoot) { - m_stubProc->setRunAsRoot(runAsRoot); - RunControl::provideAskPassEntry(stub.environment); - } - - connect(m_stubProc, &Process::started, - this, &TerminalRunner::stubStarted); - connect(m_stubProc, &Process::done, - this, &TerminalRunner::stubDone); - - m_stubProc->setEnvironment(stub.environment); - m_stubProc->setWorkingDirectory(stub.workingDirectory); - - // Error message for user is delivered via a signal. - m_stubProc->setCommand(stub.command); - m_stubProc->start(); -} - -void TerminalRunner::stop() -{ - if (m_stubProc && m_stubProc->isRunning()) - m_stubProc->stop(); -} - -void TerminalRunner::stubStarted() -{ - m_applicationPid = m_stubProc->processId(); - m_applicationMainThreadId = m_stubProc->applicationMainThreadId(); - reportStarted(); -} - -void TerminalRunner::stubDone() -{ - if (m_stubProc->error() != QProcess::UnknownError) - reportFailure(m_stubProc->errorString()); - if (m_stubProc->error() != QProcess::FailedToStart) - reportDone(); -} - } // Debugger::Internal diff --git a/src/plugins/debugger/terminal.h b/src/plugins/debugger/terminal.h index 07f334fbe8a..2efc0a38d36 100644 --- a/src/plugins/debugger/terminal.h +++ b/src/plugins/debugger/terminal.h @@ -6,18 +6,7 @@ #include #include -#include - -namespace Utils { -class Process; -class ProcessRunData; -} - -namespace Debugger { - -class DebuggerRunTool; - -namespace Internal { +namespace Debugger::Internal { class Terminal : public QObject { @@ -48,31 +37,4 @@ private: QByteArray m_slaveName; }; - -class TerminalRunner : public ProjectExplorer::RunWorker -{ -public: - TerminalRunner(ProjectExplorer::RunControl *runControl, - const std::function &stubRunnable); - - qint64 applicationPid() const { return m_applicationPid; } - qint64 applicationMainThreadId() const { return m_applicationMainThreadId; } - - void kickoffProcess(); - void interrupt(); - -private: - void start() final; - void stop() final; - - void stubStarted(); - void stubDone(); - - Utils::Process *m_stubProc = nullptr; - std::function m_stubRunnable; - qint64 m_applicationPid = 0; - qint64 m_applicationMainThreadId = 0; -}; - -} // namespace Internal -} // namespace Debugger +} // namespace Debugger::Internal