forked from qt-creator/qt-creator
CoreGdbAdapter: improve finding the exe from a core file
- added a function which tries to find the executable belonging
to a core file if the extracted path does not exist
- tries to find binaries with a relative path
- tires to remove commandline arguments, since the core
file does not store which part is the exe name (which can
contain spaces), and which are arguments
loading /QT/core which was created by "/QT/bin/exec w.." by calling
"./bin/exec with spaces" arg1 arg2 now finds the binary
==== will be split into a separate commit, included to show the
second use of the new function
LoadCoreDialog: change when ExecFilename is set from core
- only set the name if the exe exists
- if it does not exist and the previous entry does not either
then insert what was extracted from the corefile
Change-Id: I4a9846761c91ed976f3ba38a7dc756fc30ed179c
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include <debugger/debuggerstartparameters.h>
|
#include <debugger/debuggerstartparameters.h>
|
||||||
#include <debugger/debuggerstringutils.h>
|
#include <debugger/debuggerstringutils.h>
|
||||||
|
|
||||||
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -89,11 +90,49 @@ void GdbCoreEngine::setupEngine()
|
|||||||
unpackCoreIfNeeded();
|
unpackCoreIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString readExecutableNameFromCore(const QString &debuggerCommand, const QString &coreFile, bool *isCore)
|
static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile)
|
||||||
{
|
{
|
||||||
|
if (QFileInfo(fileNameFromCore).isFile())
|
||||||
|
return fileNameFromCore;
|
||||||
|
if (fileNameFromCore.isEmpty())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
// turn the filename into an absolute path, using the location of the core as a hint
|
||||||
|
QString absPath;
|
||||||
|
QFileInfo fi(fileNameFromCore);
|
||||||
|
if (fi.isAbsolute()) {
|
||||||
|
absPath = fileNameFromCore;
|
||||||
|
} else {
|
||||||
|
QFileInfo coreInfo(coreFile);
|
||||||
|
QDir coreDir = coreInfo.dir();
|
||||||
|
absPath = FileUtils::resolvePath(coreDir.absolutePath(), fileNameFromCore);
|
||||||
|
}
|
||||||
|
if (QFileInfo(absPath).isFile() || absPath.isEmpty())
|
||||||
|
return absPath;
|
||||||
|
|
||||||
|
// remove possible trailing arguments
|
||||||
|
QLatin1Char sep(' ');
|
||||||
|
QStringList pathFragments = absPath.split(sep);
|
||||||
|
while (pathFragments.size() > 0) {
|
||||||
|
QString joined_path = pathFragments.join(sep);
|
||||||
|
if (QFileInfo(joined_path).isFile()) {
|
||||||
|
return joined_path;
|
||||||
|
}
|
||||||
|
pathFragments.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
GdbCoreEngine::CoreInfo
|
||||||
|
GdbCoreEngine::readExecutableNameFromCore(const QString &debuggerCommand, const QString &coreFile)
|
||||||
|
{
|
||||||
|
CoreInfo cinfo;
|
||||||
#if 0
|
#if 0
|
||||||
ElfReader reader(coreFileName());
|
ElfReader reader(coreFile);
|
||||||
return QString::fromLocal8Bit(reader.readCoreName(isCore));
|
cinfo.isCore = false;
|
||||||
|
cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore));
|
||||||
|
cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
|
||||||
#else
|
#else
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args.append(QLatin1String("-nx"));
|
args.append(QLatin1String("-nx"));
|
||||||
@@ -116,13 +155,15 @@ QString readExecutableNameFromCore(const QString &debuggerCommand, const QString
|
|||||||
pos1 += 23;
|
pos1 += 23;
|
||||||
int pos2 = ba.indexOf('\'', pos1);
|
int pos2 = ba.indexOf('\'', pos1);
|
||||||
if (pos2 != -1) {
|
if (pos2 != -1) {
|
||||||
*isCore = true;
|
cinfo.isCore = true;
|
||||||
return QString::fromLocal8Bit(ba.mid(pos1, pos2 - pos1));
|
cinfo.rawStringFromCore = QString::fromLocal8Bit(ba.mid(pos1, pos2 - pos1));
|
||||||
|
cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString();
|
cinfo.isCore = false;
|
||||||
#endif
|
#endif
|
||||||
|
return cinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbCoreEngine::continueSetupEngine()
|
void GdbCoreEngine::continueSetupEngine()
|
||||||
@@ -136,17 +177,12 @@ void GdbCoreEngine::continueSetupEngine()
|
|||||||
m_tempCoreFile.close();
|
m_tempCoreFile.close();
|
||||||
}
|
}
|
||||||
if (isCore && m_executable.isEmpty()) {
|
if (isCore && m_executable.isEmpty()) {
|
||||||
// Read executable from core.
|
GdbCoreEngine::CoreInfo cinfo = readExecutableNameFromCore(
|
||||||
isCore = false;
|
startParameters().debuggerCommand,
|
||||||
m_executable = readExecutableNameFromCore(
|
coreFileName());
|
||||||
startParameters().debuggerCommand,
|
|
||||||
coreFileName(), &isCore);
|
|
||||||
|
|
||||||
if (isCore) {
|
if (cinfo.isCore) {
|
||||||
// Strip off command line arguments. FIXME: make robust.
|
m_executable = cinfo.foundExecutableName;
|
||||||
int idx = m_executable.indexOf(QLatin1Char(' '));
|
|
||||||
if (idx >= 0)
|
|
||||||
m_executable.truncate(idx);
|
|
||||||
if (m_executable.isEmpty()) {
|
if (m_executable.isEmpty()) {
|
||||||
showMessageBox(QMessageBox::Warning,
|
showMessageBox(QMessageBox::Warning,
|
||||||
tr("Error Loading Symbols"),
|
tr("Error Loading Symbols"),
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ namespace Internal {
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
QString readExecutableNameFromCore(const QString &cmd, const QString &coreFile, bool *isCore);
|
|
||||||
|
|
||||||
class GdbCoreEngine : public GdbEngine
|
class GdbCoreEngine : public GdbEngine
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -53,6 +51,13 @@ public:
|
|||||||
explicit GdbCoreEngine(const DebuggerStartParameters &startParameters);
|
explicit GdbCoreEngine(const DebuggerStartParameters &startParameters);
|
||||||
~GdbCoreEngine();
|
~GdbCoreEngine();
|
||||||
|
|
||||||
|
struct CoreInfo
|
||||||
|
{
|
||||||
|
QString rawStringFromCore;
|
||||||
|
QString foundExecutableName; // empty if no corresponding exec could be found
|
||||||
|
bool isCore;
|
||||||
|
};
|
||||||
|
static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile);
|
||||||
private:
|
private:
|
||||||
void setupEngine();
|
void setupEngine();
|
||||||
void setupInferior();
|
void setupInferior();
|
||||||
|
|||||||
@@ -367,10 +367,12 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
|
|||||||
Kit *k = d->kitChooser->currentKit();
|
Kit *k = d->kitChooser->currentKit();
|
||||||
QTC_ASSERT(k, return);
|
QTC_ASSERT(k, return);
|
||||||
FileName cmd = DebuggerKitInformation::debuggerCommand(k);
|
FileName cmd = DebuggerKitInformation::debuggerCommand(k);
|
||||||
bool isCore = false;
|
GdbCoreEngine::CoreInfo cinfo =
|
||||||
const QString exe = readExecutableNameFromCore(cmd.toString(), core, &isCore);
|
GdbCoreEngine::readExecutableNameFromCore(cmd.toString(), core);
|
||||||
if (!exe.isEmpty())
|
if (!cinfo.foundExecutableName.isEmpty())
|
||||||
d->localExecFileName->setFileName(FileName::fromString(exe));
|
d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName));
|
||||||
|
else if (!d->localExecFileName->isValid() && !cinfo.rawStringFromCore.isEmpty())
|
||||||
|
d->localExecFileName->setFileName(FileName::fromString(cinfo.rawStringFromCore));
|
||||||
}
|
}
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user