forked from qt-creator/qt-creator
Debugger: Move core file unpacking into RunWorker of its own
Change-Id: I99b7e6fc8eb9054a4135f693581575c3b8b541df Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -55,6 +55,8 @@
|
|||||||
#include <utils/portlist.h>
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
#include <utils/temporarydirectory.h>
|
||||||
|
#include <utils/temporaryfile.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
@@ -174,10 +176,73 @@ public:
|
|||||||
Utils::QtcProcess m_proc;
|
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<void (QProcess::*)(int)>(&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
|
class DebuggerRunToolPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPointer<TerminalRunner> terminalRunner;
|
QPointer<TerminalRunner> terminalRunner;
|
||||||
|
QPointer<CoreUnpacker> coreUnpacker;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -374,6 +439,11 @@ void DebuggerRunTool::setStartMessage(const QString &msg)
|
|||||||
|
|
||||||
void DebuggerRunTool::setCoreFileName(const QString &coreFile, bool isSnapshot)
|
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.coreFile = coreFile;
|
||||||
m_runParameters.isSnapshot = isSnapshot;
|
m_runParameters.isSnapshot = isSnapshot;
|
||||||
}
|
}
|
||||||
@@ -444,6 +514,9 @@ void DebuggerRunTool::start()
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (d->coreUnpacker)
|
||||||
|
m_runParameters.coreFile = d->coreUnpacker->coreFileName();
|
||||||
|
|
||||||
if (!fixupParameters())
|
if (!fixupParameters())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -67,7 +67,6 @@
|
|||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
#include <utils/savedaction.h>
|
#include <utils/savedaction.h>
|
||||||
#include <utils/synchronousprocess.h>
|
#include <utils/synchronousprocess.h>
|
||||||
#include <utils/temporarydirectory.h>
|
|
||||||
#include <utils/temporaryfile.h>
|
#include <utils/temporaryfile.h>
|
||||||
|
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
@@ -219,21 +218,6 @@ GdbEngine::GdbEngine()
|
|||||||
|
|
||||||
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);
|
//ExtensionSystem::PluginManager::removeObject(m_debugInfoTaskHandler);
|
||||||
delete m_debugInfoTaskHandler;
|
delete m_debugInfoTaskHandler;
|
||||||
m_debugInfoTaskHandler = 0;
|
m_debugInfoTaskHandler = 0;
|
||||||
@@ -4343,12 +4327,7 @@ void GdbEngine::setupEngine()
|
|||||||
CHECK_STATE(EngineSetupRequested);
|
CHECK_STATE(EngineSetupRequested);
|
||||||
showMessage("TRYING TO START ADAPTER");
|
showMessage("TRYING TO START ADAPTER");
|
||||||
|
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
startGdb();
|
||||||
m_executable = rp.inferior.executable;
|
|
||||||
QFileInfo fi(rp.coreFile);
|
|
||||||
m_coreName = fi.absoluteFilePath();
|
|
||||||
|
|
||||||
unpackCoreIfNeeded();
|
|
||||||
|
|
||||||
} else if (isPlainEngine()) {
|
} else if (isPlainEngine()) {
|
||||||
|
|
||||||
@@ -4369,6 +4348,8 @@ void GdbEngine::setupInferior()
|
|||||||
{
|
{
|
||||||
CHECK_STATE(InferiorSetupRequested);
|
CHECK_STATE(InferiorSetupRequested);
|
||||||
|
|
||||||
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
|
|
||||||
if (isAttachEngine()) {
|
if (isAttachEngine()) {
|
||||||
// Task 254674 does not want to remove them
|
// Task 254674 does not want to remove them
|
||||||
//qq->breakHandler()->removeAllBreakpoints();
|
//qq->breakHandler()->removeAllBreakpoints();
|
||||||
@@ -4377,7 +4358,6 @@ void GdbEngine::setupInferior()
|
|||||||
} else if (isRemoteEngine()) {
|
} else if (isRemoteEngine()) {
|
||||||
|
|
||||||
setLinuxOsAbi();
|
setLinuxOsAbi();
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
|
||||||
QString symbolFile;
|
QString symbolFile;
|
||||||
if (!rp.symbolFile.isEmpty()) {
|
if (!rp.symbolFile.isEmpty()) {
|
||||||
QFileInfo fi(rp.symbolFile);
|
QFileInfo fi(rp.symbolFile);
|
||||||
@@ -4438,8 +4418,30 @@ void GdbEngine::setupInferior()
|
|||||||
} else if (isCoreEngine()) {
|
} else if (isCoreEngine()) {
|
||||||
|
|
||||||
setLinuxOsAbi();
|
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.
|
// Do that first, otherwise no symbols are loaded.
|
||||||
QFileInfo fi(m_executable);
|
QFileInfo fi(executable);
|
||||||
QString path = fi.absoluteFilePath();
|
QString path = fi.absoluteFilePath();
|
||||||
runCommand({"-file-exec-and-symbols \"" + path + '"',
|
runCommand({"-file-exec-and-symbols \"" + path + '"',
|
||||||
CB(handleFileExecAndSymbols)});
|
CB(handleFileExecAndSymbols)});
|
||||||
@@ -4501,7 +4503,7 @@ void GdbEngine::runEngine()
|
|||||||
|
|
||||||
} else if (isCoreEngine()) {
|
} else if (isCoreEngine()) {
|
||||||
|
|
||||||
runCommand({"target core " + coreFileName(), CB(handleTargetCore)});
|
runCommand({"target core " + runParameters().coreFile, CB(handleTargetCore)});
|
||||||
|
|
||||||
} else if (isTermEngine()) {
|
} else if (isTermEngine()) {
|
||||||
|
|
||||||
@@ -4652,7 +4654,7 @@ void GdbEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
|
|||||||
|
|
||||||
} else if (isCoreEngine()) {
|
} else if (isCoreEngine()) {
|
||||||
|
|
||||||
QString core = coreFileName();
|
QString core = runParameters().coreFile;
|
||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
showMessage(tr("Symbols found."), StatusBar);
|
showMessage(tr("Symbols found."), StatusBar);
|
||||||
handleInferiorPrepared();
|
handleInferiorPrepared();
|
||||||
@@ -4981,41 +4983,6 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger,
|
|||||||
return cinfo;
|
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)
|
void GdbEngine::handleTargetCore(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
CHECK_STATE(EngineRunRequested);
|
CHECK_STATE(EngineRunRequested);
|
||||||
@@ -5045,50 +5012,6 @@ void GdbEngine::handleCoreRoundTrip(const DebuggerResponse &response)
|
|||||||
QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols);
|
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<void (QProcess::*)(int)>(&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<void (QProcess::*)(int)>(&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)
|
void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms)
|
||||||
{
|
{
|
||||||
m_pendingBreakpointRequests = 0;
|
m_pendingBreakpointRequests = 0;
|
||||||
|
@@ -445,19 +445,10 @@ private: ////////// General Interface //////////
|
|||||||
// Core
|
// Core
|
||||||
void handleTargetCore(const DebuggerResponse &response);
|
void handleTargetCore(const DebuggerResponse &response);
|
||||||
void handleCoreRoundTrip(const DebuggerResponse &response);
|
void handleCoreRoundTrip(const DebuggerResponse &response);
|
||||||
void unpackCoreIfNeeded();
|
|
||||||
QString coreFileName() const;
|
QString coreFileName() const;
|
||||||
QString coreName() const;
|
|
||||||
|
|
||||||
void continueSetupEngine();
|
|
||||||
QString mainFunction() const;
|
QString mainFunction() const;
|
||||||
|
|
||||||
QString m_executable;
|
|
||||||
QString m_coreName;
|
|
||||||
QString m_tempCoreName;
|
|
||||||
QProcess *m_coreUnpackProcess = nullptr;
|
|
||||||
QFile m_tempCoreFile;
|
|
||||||
|
|
||||||
Utils::QtcProcess m_gdbProc;
|
Utils::QtcProcess m_gdbProc;
|
||||||
OutputCollector m_outputCollector;
|
OutputCollector m_outputCollector;
|
||||||
QString m_errorString;
|
QString m_errorString;
|
||||||
|
Reference in New Issue
Block a user