Commit bd3366d8 authored by Thomas Otto's avatar Thomas Otto Committed by hjk

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: default avatarhjk <hjk121@nokiamail.com>
parent 3e830a78
......@@ -34,6 +34,7 @@
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerstringutils.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDir>
......@@ -89,11 +90,49 @@ void GdbCoreEngine::setupEngine()
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
ElfReader reader(coreFileName());
return QString::fromLocal8Bit(reader.readCoreName(isCore));
ElfReader reader(coreFile);
cinfo.isCore = false;
cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore));
cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
#else
QStringList args;
args.append(QLatin1String("-nx"));
......@@ -116,13 +155,15 @@ QString readExecutableNameFromCore(const QString &debuggerCommand, const QString
pos1 += 23;
int pos2 = ba.indexOf('\'', pos1);
if (pos2 != -1) {
*isCore = true;
return QString::fromLocal8Bit(ba.mid(pos1, pos2 - pos1));
cinfo.isCore = true;
cinfo.rawStringFromCore = QString::fromLocal8Bit(ba.mid(pos1, pos2 - pos1));
cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
}
}
}
return QString();
cinfo.isCore = false;
#endif
return cinfo;
}
void GdbCoreEngine::continueSetupEngine()
......@@ -136,17 +177,12 @@ void GdbCoreEngine::continueSetupEngine()
m_tempCoreFile.close();
}
if (isCore && m_executable.isEmpty()) {
// Read executable from core.
isCore = false;
m_executable = readExecutableNameFromCore(
startParameters().debuggerCommand,
coreFileName(), &isCore);
if (isCore) {
// Strip off command line arguments. FIXME: make robust.
int idx = m_executable.indexOf(QLatin1Char(' '));
if (idx >= 0)
m_executable.truncate(idx);
GdbCoreEngine::CoreInfo cinfo = readExecutableNameFromCore(
startParameters().debuggerCommand,
coreFileName());
if (cinfo.isCore) {
m_executable = cinfo.foundExecutableName;
if (m_executable.isEmpty()) {
showMessageBox(QMessageBox::Warning,
tr("Error Loading Symbols"),
......
......@@ -43,8 +43,6 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
QString readExecutableNameFromCore(const QString &cmd, const QString &coreFile, bool *isCore);
class GdbCoreEngine : public GdbEngine
{
Q_OBJECT
......@@ -53,6 +51,13 @@ public:
explicit GdbCoreEngine(const DebuggerStartParameters &startParameters);
~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:
void setupEngine();
void setupInferior();
......
......@@ -367,10 +367,12 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
Kit *k = d->kitChooser->currentKit();
QTC_ASSERT(k, return);
FileName cmd = DebuggerKitInformation::debuggerCommand(k);
bool isCore = false;
const QString exe = readExecutableNameFromCore(cmd.toString(), core, &isCore);
if (!exe.isEmpty())
d->localExecFileName->setFileName(FileName::fromString(exe));
GdbCoreEngine::CoreInfo cinfo =
GdbCoreEngine::readExecutableNameFromCore(cmd.toString(), core);
if (!cinfo.foundExecutableName.isEmpty())
d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName));
else if (!d->localExecFileName->isValid() && !cinfo.rawStringFromCore.isEmpty())
d->localExecFileName->setFileName(FileName::fromString(cinfo.rawStringFromCore));
}
changed();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment