Debugger: Move sub-recipes outside of DebuggerRunToolPrivate

So that it may be reused in new approach.
Enclose DebuggerRunParameters inside storage,
and operate only on it.

Task-number: QTCREATORBUG-29168
Change-Id: I24f1a3b33197b4b8bb8742d82129ae67fbc6e07f
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2025-04-16 17:28:37 +02:00
parent c5c74269c1
commit d7f49a5874

View File

@@ -128,16 +128,6 @@ private:
class DebuggerRunToolPrivate class DebuggerRunToolPrivate
{ {
public: public:
ExecutableItem coreFileRecipe(const Storage<FilePath> &tempCoreFileStorage);
ExecutableItem terminalRecipe(const SingleBarrier &barrier,
const Storage<EnginesDriver> &driverStorage,
const Storage<std::unique_ptr<Process>> &terminalStorage);
ExecutableItem fixupParamsRecipe();
ExecutableItem debugServerRecipe(const SingleBarrier &barrier);
ExecutableItem startEnginesRecipe(const Storage<EnginesDriver> &driverStorage);
ExecutableItem finalizeRecipe(const Storage<EnginesDriver> &driverStorage,
const Storage<std::unique_ptr<Process> > &terminalStorage);
DebuggerRunTool *q = nullptr; DebuggerRunTool *q = nullptr;
DebuggerRunParameters m_runParameters; DebuggerRunParameters m_runParameters;
@@ -147,15 +137,17 @@ public:
} // namespace Internal } // namespace Internal
ExecutableItem DebuggerRunToolPrivate::coreFileRecipe(const Storage<FilePath> &tempCoreFileStorage) ExecutableItem coreFileRecipe(RunControl *runControl,
const Storage<DebuggerRunParameters> &parametersStorage,
const Storage<FilePath> &tempCoreFileStorage)
{ {
const FilePath coreFile = m_runParameters.coreFile();
if (!coreFile.endsWith(".gz") && !coreFile.endsWith(".lzo"))
return Group {};
const Storage<QFile> storage; // tempCoreFile const Storage<QFile> storage; // tempCoreFile
const auto onSetup = [this, storage, coreFile, tempCoreFileStorage](Process &process) { const auto onSetup = [runControl, parametersStorage, storage, tempCoreFileStorage](Process &process) {
const FilePath coreFile = parametersStorage->coreFile();
if (!coreFile.endsWith(".gz") && !coreFile.endsWith(".lzo"))
return SetupResult::StopWithSuccess;
{ {
TemporaryFile tmp("tmpcore-XXXXXX"); TemporaryFile tmp("tmpcore-XXXXXX");
QTC_CHECK(tmp.open()); QTC_CHECK(tmp.open());
@@ -164,7 +156,7 @@ ExecutableItem DebuggerRunToolPrivate::coreFileRecipe(const Storage<FilePath> &t
QFile *tempCoreFile = storage.activeStorage(); QFile *tempCoreFile = storage.activeStorage();
process.setWorkingDirectory(TemporaryDirectory::masterDirectoryFilePath()); process.setWorkingDirectory(TemporaryDirectory::masterDirectoryFilePath());
const QString msg = Tr::tr("Unpacking core file to %1"); const QString msg = Tr::tr("Unpacking core file to %1");
q->appendMessage(msg.arg(tempCoreFileStorage->toUserOutput()), LogMessageFormat); runControl->postMessage(msg.arg(tempCoreFileStorage->toUserOutput()), LogMessageFormat);
if (coreFile.endsWith(".lzo")) { if (coreFile.endsWith(".lzo")) {
process.setCommand({"lzop", {"-o", tempCoreFileStorage->path(), "-x", coreFile.path()}}); process.setCommand({"lzop", {"-o", tempCoreFileStorage->path(), "-x", coreFile.path()}});
@@ -177,13 +169,15 @@ ExecutableItem DebuggerRunToolPrivate::coreFileRecipe(const Storage<FilePath> &t
}); });
process.setCommand({"gzip", {"-c", "-d", coreFile.path()}}); process.setCommand({"gzip", {"-c", "-d", coreFile.path()}});
} }
return SetupResult::Continue;
}; };
const auto onDone = [this, storage, tempCoreFileStorage](DoneWith result) { const auto onDone = [runControl, parametersStorage, storage, tempCoreFileStorage](DoneWith result) {
if (result == DoneWith::Success) if (result == DoneWith::Success)
m_runParameters.setCoreFilePath(*tempCoreFileStorage); parametersStorage->setCoreFilePath(*tempCoreFileStorage);
else else
q->reportFailure("Error unpacking " + m_runParameters.coreFile().toUserOutput()); runControl->postMessage("Error unpacking " + parametersStorage->coreFile().toUserOutput(),
ErrorMessageFormat);
if (storage->isOpen()) if (storage->isOpen())
storage->close(); storage->close();
}; };
@@ -194,26 +188,28 @@ ExecutableItem DebuggerRunToolPrivate::coreFileRecipe(const Storage<FilePath> &t
}; };
} }
ExecutableItem DebuggerRunToolPrivate::terminalRecipe(const SingleBarrier &barrier, ExecutableItem terminalRecipe(const Storage<DebuggerRunParameters> &parametersStorage,
const Storage<EnginesDriver> &driverStorage, const Storage<EnginesDriver> &driverStorage,
const Storage<std::unique_ptr<Process>> &terminalStorage) const Storage<std::unique_ptr<Process>> &terminalStorage,
const SingleBarrier &barrier)
{ {
const auto onSetup = [this, barrier, driverStorage, terminalStorage] { const auto onSetup = [barrier, parametersStorage, driverStorage, terminalStorage] {
const bool useCdbConsole = m_runParameters.cppEngineType() == CdbEngineType DebuggerRunParameters &runParameters = *parametersStorage;
&& (m_runParameters.startMode() == StartInternal const bool useCdbConsole = runParameters.cppEngineType() == CdbEngineType
|| m_runParameters.startMode() == StartExternal) && (runParameters.startMode() == StartInternal
|| runParameters.startMode() == StartExternal)
&& settings().useCdbConsole(); && settings().useCdbConsole();
if (useCdbConsole) if (useCdbConsole)
m_runParameters.setUseTerminal(false); runParameters.setUseTerminal(false);
if (!m_runParameters.useTerminal()) { if (!runParameters.useTerminal()) {
barrier->barrier()->advance(); barrier->barrier()->advance();
return; return;
} }
Process *process = new Process; Process *process = new Process;
terminalStorage->reset(process); terminalStorage->reset(process);
ProcessRunData stub = m_runParameters.inferior(); ProcessRunData stub = runParameters.inferior();
if (m_runParameters.runAsRoot()) { if (runParameters.runAsRoot()) {
process->setRunAsRoot(true); process->setRunAsRoot(true);
RunControl::provideAskPassEntry(stub.environment); RunControl::provideAskPassEntry(stub.environment);
} }
@@ -221,9 +217,9 @@ ExecutableItem DebuggerRunToolPrivate::terminalRecipe(const SingleBarrier &barri
process->setRunData(stub); process->setRunData(stub);
QObject::connect(process, &Process::started, process, QObject::connect(process, &Process::started, process,
[this, process, barrier = barrier->barrier()] { [runParameters = &runParameters, process, barrier = barrier->barrier()] {
m_runParameters.setApplicationPid(process->processId()); runParameters->setApplicationPid(process->processId());
m_runParameters.setApplicationMainThreadId(process->applicationMainThreadId()); runParameters->setApplicationMainThreadId(process->applicationMainThreadId());
barrier->advance(); barrier->advance();
}); });
@@ -238,44 +234,46 @@ ExecutableItem DebuggerRunToolPrivate::terminalRecipe(const SingleBarrier &barri
return Sync(onSetup); return Sync(onSetup);
} }
ExecutableItem DebuggerRunToolPrivate::fixupParamsRecipe() ExecutableItem fixupParamsRecipe(RunControl *runControl,
const Storage<DebuggerRunParameters> &parametersStorage)
{ {
return Sync([this] { return Sync([runControl, parametersStorage] {
DebuggerRunParameters &runParameters = *parametersStorage;
TaskHub::clearTasks(Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); TaskHub::clearTasks(Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
if (q->runControl()->usesDebugChannel()) if (runControl->usesDebugChannel())
m_runParameters.setRemoteChannel(q->runControl()->debugChannel().toString()); runParameters.setRemoteChannel(runControl->debugChannel().toString());
if (q->runControl()->usesQmlChannel()) { if (runControl->usesQmlChannel()) {
m_runParameters.setQmlServer(q->runControl()->qmlChannel()); runParameters.setQmlServer(runControl->qmlChannel());
if (m_runParameters.isAddQmlServerInferiorCmdArgIfNeeded() if (runParameters.isAddQmlServerInferiorCmdArgIfNeeded()
&& m_runParameters.isQmlDebugging() && runParameters.isQmlDebugging()
&& m_runParameters.isCppDebugging()) { && runParameters.isCppDebugging()) {
const int qmlServerPort = m_runParameters.qmlServer().port(); const int qmlServerPort = runParameters.qmlServer().port();
QTC_ASSERT(qmlServerPort > 0, q->reportFailure(); return false); QTC_ASSERT(qmlServerPort > 0, return false);
const QString mode = QString("port:%1").arg(qmlServerPort); const QString mode = QString("port:%1").arg(qmlServerPort);
auto inferior = m_runParameters.inferior(); auto inferior = runParameters.inferior();
CommandLine cmd{inferior.command.executable()}; CommandLine cmd{inferior.command.executable()};
cmd.addArg(qmlDebugCommandLineArguments(QmlDebuggerServices, mode, true)); cmd.addArg(qmlDebugCommandLineArguments(QmlDebuggerServices, mode, true));
cmd.addArgs(m_runParameters.inferior().command.arguments(), CommandLine::Raw); cmd.addArgs(runParameters.inferior().command.arguments(), CommandLine::Raw);
inferior.command = cmd; inferior.command = cmd;
m_runParameters.setInferior(inferior); runParameters.setInferior(inferior);
} }
} }
// User canceled input dialog asking for executable when working on library project. // User canceled input dialog asking for executable when working on library project.
if (m_runParameters.startMode() == StartInternal if (runParameters.startMode() == StartInternal
&& m_runParameters.inferior().command.isEmpty() && runParameters.inferior().command.isEmpty()
&& m_runParameters.interpreter().isEmpty()) { && runParameters.interpreter().isEmpty()) {
q->reportFailure(Tr::tr("No executable specified.")); runControl->postMessage(Tr::tr("No executable specified."), ErrorMessageFormat);
return false; return false;
} }
// QML and/or mixed are not prepared for it. // QML and/or mixed are not prepared for it.
// q->runControl()->setSupportsReRunning(!q->m_runParameters.isQmlDebugging); // runControl->setSupportsReRunning(!q->m_runParameters.isQmlDebugging);
q->runControl()->setSupportsReRunning(false); // FIXME: Broken in general. runControl->setSupportsReRunning(false); // FIXME: Broken in general.
// FIXME: Disabled due to Android. Make Android device report available ports instead. // FIXME: Disabled due to Android. Make Android device report available ports instead.
// int neededPorts = 0; // int neededPorts = 0;
@@ -288,34 +286,35 @@ ExecutableItem DebuggerRunToolPrivate::fixupParamsRecipe()
// return; // return;
// } // }
if (Result<> res = m_runParameters.fixupParameters(q->runControl()); !res) { if (Result<> res = runParameters.fixupParameters(runControl); !res) {
q->reportFailure(res.error()); runControl->postMessage(res.error(), ErrorMessageFormat);
return false; return false;
} }
if (m_runParameters.cppEngineType() == CdbEngineType if (runParameters.cppEngineType() == CdbEngineType
&& Utils::is64BitWindowsBinary(m_runParameters.inferior().command.executable()) && Utils::is64BitWindowsBinary(runParameters.inferior().command.executable())
&& !Utils::is64BitWindowsBinary(m_runParameters.debugger().command.executable())) { && !Utils::is64BitWindowsBinary(runParameters.debugger().command.executable())) {
q->reportFailure(Tr::tr( runControl->postMessage(Tr::tr(
"%1 is a 64 bit executable which can not be debugged by a 32 bit Debugger.\n" "%1 is a 64 bit executable which can not be debugged by a 32 bit Debugger.\n"
"Please select a 64 bit Debugger in the kit settings for this kit.") "Please select a 64 bit Debugger in the kit settings for this kit.")
.arg(m_runParameters.inferior().command.executable().toUserOutput())); .arg(runParameters.inferior().command.executable().toUserOutput()),
ErrorMessageFormat);
return false; return false;
} }
Utils::globalMacroExpander()->registerFileVariables( Utils::globalMacroExpander()->registerFileVariables(
"DebuggedExecutable", Tr::tr("Debugged executable"), "DebuggedExecutable", Tr::tr("Debugged executable"),
[this] { return m_runParameters.inferior().command.executable(); }); [exec = runParameters.inferior().command.executable()] { return exec; });
q->runControl()->setDisplayName(m_runParameters.displayName()); runControl->setDisplayName(runParameters.displayName());
if (auto interpreterAspect = q->runControl()->aspectData<FilePathAspect>()) { if (auto interpreterAspect = runControl->aspectData<FilePathAspect>()) {
if (auto mainScriptAspect = q->runControl()->aspectData<MainScriptAspect>()) { if (auto mainScriptAspect = runControl->aspectData<MainScriptAspect>()) {
const FilePath mainScript = mainScriptAspect->filePath; const FilePath mainScript = mainScriptAspect->filePath;
const FilePath interpreter = interpreterAspect->filePath; const FilePath interpreter = interpreterAspect->filePath;
if (!interpreter.isEmpty() && mainScript.endsWith(".py")) { if (!interpreter.isEmpty() && mainScript.endsWith(".py")) {
m_runParameters.setMainScript(mainScript); runParameters.setMainScript(mainScript);
m_runParameters.setInterpreter(interpreter); runParameters.setInterpreter(interpreter);
} }
} }
} }
@@ -324,28 +323,31 @@ ExecutableItem DebuggerRunToolPrivate::fixupParamsRecipe()
}); });
} }
ExecutableItem DebuggerRunToolPrivate::debugServerRecipe(const SingleBarrier &barrier) ExecutableItem debugServerRecipe(RunControl *runControl,
const Storage<DebuggerRunParameters> &parametersStorage,
const SingleBarrier &barrier)
{ {
const auto useDebugServer = [this] { const auto useDebugServer = [runControl, parametersStorage] {
return q->runControl()->usesDebugChannel() && !m_runParameters.skipDebugServer(); return runControl->usesDebugChannel() && !parametersStorage->skipDebugServer();
}; };
const auto onSetup = [this, barrier](Process &process) { const auto onSetup = [runControl, parametersStorage, barrier](Process &process) {
process.setUtf8Codec(); process.setUtf8Codec();
CommandLine commandLine = m_runParameters.inferior().command; DebuggerRunParameters &runParameters = *parametersStorage;
CommandLine commandLine = runParameters.inferior().command;
CommandLine cmd; CommandLine cmd;
if (q->runControl()->usesQmlChannel() && !q->runControl()->usesDebugChannel()) { if (runControl->usesQmlChannel() && !runControl->usesDebugChannel()) {
// FIXME: Case should not happen? // FIXME: Case should not happen?
cmd.setExecutable(commandLine.executable()); cmd.setExecutable(commandLine.executable());
cmd.addArg(qmlDebugTcpArguments(QmlDebuggerServices, q->runControl()->qmlChannel())); cmd.addArg(qmlDebugTcpArguments(QmlDebuggerServices, runControl->qmlChannel()));
cmd.addArgs(commandLine.arguments(), CommandLine::Raw); cmd.addArgs(commandLine.arguments(), CommandLine::Raw);
} else { } else {
cmd.setExecutable(q->runControl()->device()->debugServerPath()); cmd.setExecutable(runControl->device()->debugServerPath());
if (cmd.isEmpty()) { if (cmd.isEmpty()) {
if (q->runControl()->device()->osType() == Utils::OsTypeMac) { if (runControl->device()->osType() == Utils::OsTypeMac) {
const FilePath debugServerLocation = q->runControl()->device()->filePath( const FilePath debugServerLocation = runControl->device()->filePath(
"/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/" "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/"
"Resources/debugserver"); "Resources/debugserver");
@@ -355,15 +357,15 @@ ExecutableItem DebuggerRunToolPrivate::debugServerRecipe(const SingleBarrier &ba
// TODO: In the future it is expected that the debugserver will be // TODO: In the future it is expected that the debugserver will be
// replaced by lldb-server. Remove the check for debug server at that point. // replaced by lldb-server. Remove the check for debug server at that point.
const FilePath lldbserver const FilePath lldbserver
= q->runControl()->device()->filePath("lldb-server").searchInPath(); = runControl->device()->filePath("lldb-server").searchInPath();
if (lldbserver.isExecutableFile()) if (lldbserver.isExecutableFile())
cmd.setExecutable(lldbserver); cmd.setExecutable(lldbserver);
} }
} else { } else {
const FilePath gdbServerPath const FilePath gdbServerPath
= q->runControl()->device()->filePath("gdbserver").searchInPath(); = runControl->device()->filePath("gdbserver").searchInPath();
FilePath lldbServerPath FilePath lldbServerPath
= q->runControl()->device()->filePath("lldb-server").searchInPath(); = runControl->device()->filePath("lldb-server").searchInPath();
// TODO: Which one should we prefer? // TODO: Which one should we prefer?
if (gdbServerPath.isExecutableFile()) if (gdbServerPath.isExecutableFile())
@@ -382,78 +384,72 @@ ExecutableItem DebuggerRunToolPrivate::debugServerRecipe(const SingleBarrier &ba
} }
} }
} }
QTC_ASSERT(q->runControl()->usesDebugChannel(), QTC_ASSERT(runControl->usesDebugChannel(), return SetupResult::StopWithError);
q->reportFailure({}); return SetupResult::StopWithError);
if (cmd.executable().baseName().contains("lldb-server")) { if (cmd.executable().baseName().contains("lldb-server")) {
cmd.addArg("platform"); cmd.addArg("platform");
cmd.addArg("--listen"); cmd.addArg("--listen");
cmd.addArg(QString("*:%1").arg(q->runControl()->debugChannel().port())); cmd.addArg(QString("*:%1").arg(runControl->debugChannel().port()));
cmd.addArg("--server"); cmd.addArg("--server");
} else if (cmd.executable().baseName() == "debugserver") { } else if (cmd.executable().baseName() == "debugserver") {
const QString ipAndPort("`echo $SSH_CLIENT | cut -d ' ' -f 1`:%1"); const QString ipAndPort("`echo $SSH_CLIENT | cut -d ' ' -f 1`:%1");
cmd.addArgs(ipAndPort.arg(q->runControl()->debugChannel().port()), CommandLine::Raw); cmd.addArgs(ipAndPort.arg(runControl->debugChannel().port()), CommandLine::Raw);
if (m_runParameters.serverAttachPid().isValid()) if (runParameters.serverAttachPid().isValid())
cmd.addArgs({"--attach", QString::number(m_runParameters.serverAttachPid().pid())}); cmd.addArgs({"--attach", QString::number(runParameters.serverAttachPid().pid())});
else else
cmd.addCommandLineAsArgs(q->runControl()->commandLine()); cmd.addCommandLineAsArgs(runControl->commandLine());
} else { } else {
// Something resembling gdbserver // Something resembling gdbserver
if (m_runParameters.serverUseMulti()) if (runParameters.serverUseMulti())
cmd.addArg("--multi"); cmd.addArg("--multi");
if (m_runParameters.serverAttachPid().isValid()) if (runParameters.serverAttachPid().isValid())
cmd.addArg("--attach"); cmd.addArg("--attach");
const auto port = q->runControl()->debugChannel().port(); const auto port = runControl->debugChannel().port();
cmd.addArg(QString(":%1").arg(port)); cmd.addArg(QString(":%1").arg(port));
if (q->runControl()->device()->extraData(ProjectExplorer::Constants::SSH_FORWARD_DEBUGSERVER_PORT).toBool()) { if (runControl->device()->extraData(ProjectExplorer::Constants::SSH_FORWARD_DEBUGSERVER_PORT).toBool()) {
QVariantHash extraData; QVariantHash extraData;
extraData[RemoteLinux::Constants::SshForwardPort] = port; extraData[RemoteLinux::Constants::SshForwardPort] = port;
extraData[RemoteLinux::Constants::DisableSharing] = true; extraData[RemoteLinux::Constants::DisableSharing] = true;
process.setExtraData(extraData); process.setExtraData(extraData);
} }
if (m_runParameters.serverAttachPid().isValid()) if (runParameters.serverAttachPid().isValid())
cmd.addArg(QString::number(m_runParameters.serverAttachPid().pid())); cmd.addArg(QString::number(runParameters.serverAttachPid().pid()));
} }
} }
if (auto terminalAspect = q->runControl()->aspectData<TerminalAspect>()) { if (auto terminalAspect = runControl->aspectData<TerminalAspect>()) {
const bool useTerminal = terminalAspect->useTerminal; const bool useTerminal = terminalAspect->useTerminal;
process.setTerminalMode(useTerminal ? TerminalMode::Run : TerminalMode::Off); process.setTerminalMode(useTerminal ? TerminalMode::Run : TerminalMode::Off);
} }
process.setCommand(cmd); process.setCommand(cmd);
process.setWorkingDirectory(m_runParameters.inferior().workingDirectory); process.setWorkingDirectory(runParameters.inferior().workingDirectory);
QObject::connect(&process, &Process::readyReadStandardOutput, q, [this, process = &process] { QObject::connect(&process, &Process::readyReadStandardOutput, runControl,
const QString msg = process->readAllStandardOutput(); [runControl, process = &process] {
q->runControl()->postMessage(msg, StdOutFormat, false); runControl->postMessage(process->readAllStandardOutput(), StdOutFormat, false);
}); });
QObject::connect(&process, &Process::readyReadStandardError, q, [this, process = &process] { QObject::connect(&process, &Process::readyReadStandardError, runControl,
const QString msg = process->readAllStandardError(); [runControl, process = &process] {
q->runControl()->postMessage(msg, StdErrFormat, false); runControl->postMessage(process->readAllStandardError(), StdErrFormat, false);
}); });
QObject::connect(&process, &Process::started, q, [barrier = barrier->barrier()] { QObject::connect(&process, &Process::started, barrier->barrier(), &Barrier::advance);
barrier->advance();
});
return SetupResult::Continue; return SetupResult::Continue;
}; };
const auto onDone = [this](const Process &process, DoneWith result) { const auto onDone = [runControl](const Process &process) {
if (result != DoneWith::Success) runControl->postMessage(process.errorString(), ErrorMessageFormat);
q->reportFailure(process.errorString());
else
q->reportDone();
}; };
return Group { return Group {
If (useDebugServer) >> Then { If (useDebugServer) >> Then {
ProcessTask(onSetup, onDone) ProcessTask(onSetup, onDone, CallDoneIf::Error)
} >> Else { } >> Else {
Sync([barrier] { barrier->barrier()->advance(); }) Sync([barrier] { barrier->barrier()->advance(); })
} }
@@ -468,13 +464,15 @@ static ExecutableItem doneAwaiter(const Storage<EnginesDriver> &driverStorage)
}); });
} }
ExecutableItem DebuggerRunToolPrivate::startEnginesRecipe(const Storage<EnginesDriver> &driverStorage) ExecutableItem startEnginesRecipe(RunControl *runControl,
const Storage<DebuggerRunParameters> &parametersStorage,
const Storage<EnginesDriver> &driverStorage)
{ {
const auto setupEngines = [this, driverStorage] { const auto setupEngines = [runControl, parametersStorage, driverStorage] {
DebuggerRunParameters &runParameters = *parametersStorage;
EnginesDriver *driver = driverStorage.activeStorage(); EnginesDriver *driver = driverStorage.activeStorage();
RunControl *rc = q->runControl(); if (Result<> res = driver->setupEngines(runControl, runParameters); !res) {
if (Result<> res = driver->setupEngines(rc, m_runParameters); !res) { runControl->postMessage(res.error(), ErrorMessageFormat);
q->reportFailure(res.error());
return false; return false;
} }
if (Result<> res = driver->checkBreakpoints(); !res) { if (Result<> res = driver->checkBreakpoints(); !res) {
@@ -489,10 +487,10 @@ ExecutableItem DebuggerRunToolPrivate::startEnginesRecipe(const Storage<EnginesD
} }
} }
} }
rc->postMessage(Tr::tr("Debugging %1 ...").arg(m_runParameters.inferior().command.toUserOutput()), runControl->postMessage(Tr::tr("Debugging %1 ...").arg(runParameters.inferior().command.toUserOutput()),
NormalMessageFormat); NormalMessageFormat);
const QString message = Tr::tr("Starting debugger \"%1\" for ABI \"%2\"...") const QString message = Tr::tr("Starting debugger \"%1\" for ABI \"%2\"...")
.arg(driver->debuggerName(), m_runParameters.toolChainAbi().toString()); .arg(driver->debuggerName(), runParameters.toolChainAbi().toString());
DebuggerMainWindow::showStatusMessage(message, 10000); DebuggerMainWindow::showStatusMessage(message, 10000);
driver->showMessage(driver->startParameters(), LogDebug); driver->showMessage(driver->startParameters(), LogDebug);
driver->showMessage(DebuggerSettings::dump(), LogDebug); driver->showMessage(DebuggerSettings::dump(), LogDebug);
@@ -516,8 +514,8 @@ static ExecutableItem terminalAwaiter(const Storage<std::unique_ptr<Process>> &t
}); });
} }
ExecutableItem DebuggerRunToolPrivate::finalizeRecipe(const Storage<EnginesDriver> &driverStorage, ExecutableItem finalizeRecipe(const Storage<EnginesDriver> &driverStorage,
const Storage<std::unique_ptr<Process>> &terminalStorage) const Storage<std::unique_ptr<Process>> &terminalStorage)
{ {
const auto isRunning = [driverStorage] { return driverStorage->isRunning(); }; const auto isRunning = [driverStorage] { return driverStorage->isRunning(); };
const auto isTerminalRunning = [terminalStorage] { const auto isTerminalRunning = [terminalStorage] {
@@ -730,49 +728,53 @@ void EnginesDriver::showMessage(const QString &msg, int channel, int timeout)
void DebuggerRunTool::start() void DebuggerRunTool::start()
{ {
const Storage<DebuggerRunParameters> parametersStorage;
const Storage<EnginesDriver> driverStorage; const Storage<EnginesDriver> driverStorage;
const Storage<FilePath> tempCoreFileStorage; const Storage<FilePath> tempCoreFileStorage;
const Storage<std::unique_ptr<Process>> terminalStorage; const Storage<std::unique_ptr<Process>> terminalStorage;
const auto onSetup = [this] { const auto onSetup = [this, parametersStorage] {
RunInterface *iface = runStorage().activeStorage(); RunInterface *iface = runStorage().activeStorage();
connect(this, &DebuggerRunTool::canceled, iface, &RunInterface::canceled); connect(this, &DebuggerRunTool::canceled, iface, &RunInterface::canceled);
connect(iface, &RunInterface::started, this, &RunWorker::reportStarted); connect(iface, &RunInterface::started, this, &RunWorker::reportStarted);
d->m_runParameters.setAttachPid(runControl()->attachPid()); *parametersStorage = d->m_runParameters;
parametersStorage->setAttachPid(runControl()->attachPid());
}; };
const auto terminalKicker = [this, driverStorage, terminalStorage](const SingleBarrier &barrier) { const auto terminalKicker = [parametersStorage, driverStorage, terminalStorage]
return d->terminalRecipe(barrier, driverStorage, terminalStorage); (const SingleBarrier &barrier) {
return terminalRecipe(parametersStorage, driverStorage, terminalStorage, barrier);
}; };
const auto debugServerKicker = [this](const SingleBarrier &barrier) { const auto debugServerKicker = [runControl = runControl(), parametersStorage](const SingleBarrier &barrier) {
return d->debugServerRecipe(barrier); return debugServerRecipe(runControl, parametersStorage, barrier);
}; };
const auto onDone = [this, tempCoreFileStorage] { const auto onDone = [parametersStorage, tempCoreFileStorage] {
if (tempCoreFileStorage->exists()) if (tempCoreFileStorage->exists())
tempCoreFileStorage->removeFile(); tempCoreFileStorage->removeFile();
if (d->m_runParameters.isSnapshot() && !d->m_runParameters.coreFile().isEmpty()) if (parametersStorage->isSnapshot() && !parametersStorage->coreFile().isEmpty())
d->m_runParameters.coreFile().removeFile(); parametersStorage->coreFile().removeFile();
}; };
const Group recipe { const Group recipe {
runStorage(), runStorage(),
parametersStorage,
driverStorage, driverStorage,
terminalStorage, terminalStorage,
tempCoreFileStorage, tempCoreFileStorage,
continueOnError, continueOnError,
onGroupSetup(onSetup), onGroupSetup(onSetup),
Group { Group {
d->coreFileRecipe(tempCoreFileStorage), coreFileRecipe(runControl(), parametersStorage, tempCoreFileStorage),
When (terminalKicker) >> Do { When (terminalKicker) >> Do {
d->fixupParamsRecipe(), fixupParamsRecipe(runControl(), parametersStorage),
When (debugServerKicker) >> Do { When (debugServerKicker) >> Do {
d->startEnginesRecipe(driverStorage) startEnginesRecipe(runControl(), parametersStorage, driverStorage)
} }
} }
}.withCancel(canceler()), }.withCancel(canceler()),
d->finalizeRecipe(driverStorage, terminalStorage), finalizeRecipe(driverStorage, terminalStorage),
onGroupDone(onDone) onGroupDone(onDone)
}; };
d->m_taskTreeRunner.start(recipe, {}, [this](DoneWith result) { d->m_taskTreeRunner.start(recipe, {}, [this](DoneWith result) {