diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index cd825ca6861..88bdd39812a 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -55,6 +55,8 @@ #include #include #include +#include +#include #include #include @@ -174,10 +176,73 @@ public: Utils::QtcProcess m_proc; }; +class CoreUnpacker : public RunWorker +{ +public: + CoreUnpacker(RunControl *runControl, const QString &coreFileName) + : RunWorker(runControl), m_coreFileName(coreFileName) + {} + + QString coreFileName() const { return m_tempCoreFileName; } + +private: + ~CoreUnpacker() final + { + m_coreUnpackProcess.blockSignals(true); + m_coreUnpackProcess.terminate(); + m_coreUnpackProcess.deleteLater(); + if (m_tempCoreFile.isOpen()) + m_tempCoreFile.close(); + + QFile::remove(m_tempCoreFileName); + } + + void start() final + { + { + Utils::TemporaryFile tmp("tmpcore-XXXXXX"); + tmp.open(); + m_tempCoreFileName = tmp.fileName(); + } + + m_coreUnpackProcess.setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); + connect(&m_coreUnpackProcess, static_cast(&QProcess::finished), + this, &CoreUnpacker::reportStarted); + + const QString msg = DebuggerRunTool::tr("Unpacking core file to %1"); + appendMessage(msg.arg(m_tempCoreFileName), LogMessageFormat); + + if (m_coreFileName.endsWith(".lzo")) { + m_coreUnpackProcess.start("lzop", {"-o", m_tempCoreFileName, "-x", m_coreFileName}); + return; + } + + if (m_coreFileName.endsWith(".gz")) { + appendMessage(msg.arg(m_tempCoreFileName), LogMessageFormat); + m_tempCoreFile.setFileName(m_tempCoreFileName); + m_tempCoreFile.open(QFile::WriteOnly); + connect(&m_coreUnpackProcess, &QProcess::readyRead, this, [this] { + m_tempCoreFile.write(m_coreUnpackProcess.readAll()); + }); + m_coreUnpackProcess.start("gzip", {"-c", "-d", m_coreFileName}); + return; + } + + QTC_CHECK(false); + reportFailure("Unknown file extension in " + m_coreFileName); + } + + QFile m_tempCoreFile; + QString m_coreFileName; + QString m_tempCoreFileName; + QProcess m_coreUnpackProcess; +}; + class DebuggerRunToolPrivate { public: QPointer terminalRunner; + QPointer coreUnpacker; }; } // namespace Internal @@ -374,6 +439,11 @@ void DebuggerRunTool::setStartMessage(const QString &msg) void DebuggerRunTool::setCoreFileName(const QString &coreFile, bool isSnapshot) { + if (coreFile.endsWith(".gz") || coreFile.endsWith(".lzo")) { + d->coreUnpacker = new CoreUnpacker(runControl(), coreFile); + addStartDependency(d->coreUnpacker); + } + m_runParameters.coreFile = coreFile; m_runParameters.isSnapshot = isSnapshot; } @@ -444,6 +514,9 @@ void DebuggerRunTool::start() // return; // } + if (d->coreUnpacker) + m_runParameters.coreFile = d->coreUnpacker->coreFileName(); + if (!fixupParameters()) return; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2370d6f22f9..45f1afe0319 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -67,7 +67,6 @@ #include #include #include -#include #include #include @@ -219,21 +218,6 @@ GdbEngine::GdbEngine() GdbEngine::~GdbEngine() { - if (isCoreEngine()) { - if (m_coreUnpackProcess) { - m_coreUnpackProcess->blockSignals(true); - m_coreUnpackProcess->terminate(); - m_coreUnpackProcess->deleteLater(); - m_coreUnpackProcess = nullptr; - if (m_tempCoreFile.isOpen()) - m_tempCoreFile.close(); - } - if (!m_tempCoreName.isEmpty()) { - QFile tmpFile(m_tempCoreName); - tmpFile.remove(); - } - } - //ExtensionSystem::PluginManager::removeObject(m_debugInfoTaskHandler); delete m_debugInfoTaskHandler; m_debugInfoTaskHandler = 0; @@ -4343,12 +4327,7 @@ void GdbEngine::setupEngine() CHECK_STATE(EngineSetupRequested); showMessage("TRYING TO START ADAPTER"); - const DebuggerRunParameters &rp = runParameters(); - m_executable = rp.inferior.executable; - QFileInfo fi(rp.coreFile); - m_coreName = fi.absoluteFilePath(); - - unpackCoreIfNeeded(); + startGdb(); } else if (isPlainEngine()) { @@ -4369,6 +4348,8 @@ void GdbEngine::setupInferior() { CHECK_STATE(InferiorSetupRequested); + const DebuggerRunParameters &rp = runParameters(); + if (isAttachEngine()) { // Task 254674 does not want to remove them //qq->breakHandler()->removeAllBreakpoints(); @@ -4377,7 +4358,6 @@ void GdbEngine::setupInferior() } else if (isRemoteEngine()) { setLinuxOsAbi(); - const DebuggerRunParameters &rp = runParameters(); QString symbolFile; if (!rp.symbolFile.isEmpty()) { QFileInfo fi(rp.symbolFile); @@ -4438,8 +4418,30 @@ void GdbEngine::setupInferior() } else if (isCoreEngine()) { setLinuxOsAbi(); + + QString executable = rp.inferior.executable; + + if (executable.isEmpty()) { + CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(rp.debugger, rp.coreFile); + + if (!cinfo.isCore) { + AsynchronousMessageBox::warning(tr("Error Loading Core File"), + tr("The specified file does not appear to be a core file.")); + notifyInferiorSetupFailed(); + return; + } + + executable = cinfo.foundExecutableName; + if (executable.isEmpty()) { + AsynchronousMessageBox::warning(tr("Error Loading Symbols"), + tr("No executable to load symbols from specified core.")); + notifyInferiorSetupFailed(); + return; + } + } + // Do that first, otherwise no symbols are loaded. - QFileInfo fi(m_executable); + QFileInfo fi(executable); QString path = fi.absoluteFilePath(); runCommand({"-file-exec-and-symbols \"" + path + '"', CB(handleFileExecAndSymbols)}); @@ -4501,7 +4503,7 @@ void GdbEngine::runEngine() } else if (isCoreEngine()) { - runCommand({"target core " + coreFileName(), CB(handleTargetCore)}); + runCommand({"target core " + runParameters().coreFile, CB(handleTargetCore)}); } else if (isTermEngine()) { @@ -4652,7 +4654,7 @@ void GdbEngine::handleFileExecAndSymbols(const DebuggerResponse &response) } else if (isCoreEngine()) { - QString core = coreFileName(); + QString core = runParameters().coreFile; if (response.resultClass == ResultDone) { showMessage(tr("Symbols found."), StatusBar); handleInferiorPrepared(); @@ -4981,41 +4983,6 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, return cinfo; } -void GdbEngine::continueSetupEngine() -{ - if (isCoreEngine()) { - bool isCore = true; - if (m_coreUnpackProcess) { - isCore = m_coreUnpackProcess->exitCode() == 0; - m_coreUnpackProcess->deleteLater(); - m_coreUnpackProcess = 0; - if (m_tempCoreFile.isOpen()) - m_tempCoreFile.close(); - } - if (isCore && m_executable.isEmpty()) { - CoreInfo cinfo = - CoreInfo::readExecutableNameFromCore(runParameters().debugger, coreFileName()); - - if (cinfo.isCore) { - m_executable = cinfo.foundExecutableName; - if (m_executable.isEmpty()) { - AsynchronousMessageBox::warning(tr("Error Loading Symbols"), - tr("No executable to load symbols from specified core.")); - notifyEngineSetupFailed(); - return; - } - } - } - if (isCore) { - startGdb(); - } else { - AsynchronousMessageBox::warning(tr("Error Loading Core File"), - tr("The specified file does not appear to be a core file.")); - notifyEngineSetupFailed(); - } - } -} - void GdbEngine::handleTargetCore(const DebuggerResponse &response) { CHECK_STATE(EngineRunRequested); @@ -5045,50 +5012,6 @@ void GdbEngine::handleCoreRoundTrip(const DebuggerResponse &response) QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols); } -static QString tempCoreFilename() -{ - Utils::TemporaryFile tmp("tmpcore-XXXXXX"); - tmp.open(); - return tmp.fileName(); -} - -void GdbEngine::unpackCoreIfNeeded() -{ - QStringList arguments; - const QString msg = "Unpacking core file to %1"; - if (m_coreName.endsWith(".lzo")) { - m_tempCoreName = tempCoreFilename(); - showMessage(msg.arg(m_tempCoreName)); - arguments << "-o" << m_tempCoreName << "-x" << m_coreName; - m_coreUnpackProcess = new QProcess(this); - m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); - m_coreUnpackProcess->start("lzop", arguments); - connect(m_coreUnpackProcess, static_cast(&QProcess::finished), - this, &GdbEngine::continueSetupEngine); - } else if (m_coreName.endsWith(".gz")) { - m_tempCoreName = tempCoreFilename(); - showMessage(msg.arg(m_tempCoreName)); - m_tempCoreFile.setFileName(m_tempCoreName); - m_tempCoreFile.open(QFile::WriteOnly); - arguments << "-c" << "-d" << m_coreName; - m_coreUnpackProcess = new QProcess(this); - m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath()); - m_coreUnpackProcess->start("gzip", arguments); - connect(m_coreUnpackProcess, &QProcess::readyRead, this, [this] { - m_tempCoreFile.write(m_coreUnpackProcess->readAll()); - }); - connect(m_coreUnpackProcess, static_cast(&QProcess::finished), - this, &GdbEngine::continueSetupEngine); - } else { - continueSetupEngine(); - } -} - -QString GdbEngine::coreFileName() const -{ - return m_tempCoreName.isEmpty() ? m_coreName : m_tempCoreName; -} - void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) { m_pendingBreakpointRequests = 0; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 506f68c34c6..baad5be0aed 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -445,19 +445,10 @@ private: ////////// General Interface ////////// // Core void handleTargetCore(const DebuggerResponse &response); void handleCoreRoundTrip(const DebuggerResponse &response); - void unpackCoreIfNeeded(); QString coreFileName() const; - QString coreName() const; - void continueSetupEngine(); QString mainFunction() const; - QString m_executable; - QString m_coreName; - QString m_tempCoreName; - QProcess *m_coreUnpackProcess = nullptr; - QFile m_tempCoreFile; - Utils::QtcProcess m_gdbProc; OutputCollector m_outputCollector; QString m_errorString;