Commit 78aa94c8 authored by Friedemann Kleint's avatar Friedemann Kleint Committed by hjk

Debugger: Improve engine detection.

Remove the RunConfiguration parameter from guessCppEngineType()
and use the DebuggerStartParameter::toolChainAbi only.

Use fillParameter() to set the debugger command and toolchain
in order to prevent mismatches.

Add logic trying to figure out the profile to fillParameters()
in case the profile passed in is 0 for the command line cases.

Use CDB matcher for post mortem and Remote CDB, fix it to
prefer 64bit CDB on 64bit OS.

Change-Id: Icedc3883fe15660303060498ab609957e6d01cd1
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent fd8de2f4
......@@ -109,6 +109,7 @@
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <qtsupport/qtsupportconstants.h>
......@@ -122,6 +123,9 @@
#include <utils/proxyaction.h>
#include <utils/statuslabel.h>
#include <utils/fileutils.h>
#ifdef Q_OS_WIN
# include <utils/winutils.h>
#endif
#include <QComboBox>
#include <QDockWidget>
......@@ -551,10 +555,112 @@ public:
//
///////////////////////////////////////////////////////////////////////
void fillParameters(DebuggerStartParameters *sp, Profile *profile)
static inline QString executableForPid(qint64 pid)
{
foreach (const ProjectExplorer::DeviceProcess &p, ProjectExplorer::DeviceProcessList::localProcesses())
if (p.pid == pid)
return p.exe;
return QString();
}
class AbiProfileMatcher : public ProfileMatcher
{
public:
explicit AbiProfileMatcher(const QList<Abi> &abis) : m_abis(abis) {}
bool matches(const Profile *p) const
{
if (const ToolChain *tc = ToolChainProfileInformation::toolChain(p))
return m_abis.contains(tc->targetAbi());
return false;
}
private:
const QList<Abi> m_abis;
};
class CompatibleAbiProfileMatcher : public ProfileMatcher
{
public:
explicit CompatibleAbiProfileMatcher(const QList<Abi> &abis) : m_abis(abis) {}
bool matches(const Profile *p) const
{
if (const ToolChain *tc = ToolChainProfileInformation::toolChain(p))
foreach (const Abi &a, m_abis)
if (a.isCompatibleWith(tc->targetAbi()))
return true;
return false;
}
private:
const QList<Abi> m_abis;
};
class CdbMatcher : ProfileMatcher
{
public:
CdbMatcher(char wordWidth = 0) : m_wordWidth(wordWidth) {}
bool matches(const Profile *profile) const
{
const ToolChain *tc = ToolChainProfileInformation::toolChain(profile);
QTC_ASSERT(tc, return false);
const Abi abi = tc->targetAbi();
if (abi.architecture() != Abi::X86Architecture
|| abi.os() != Abi::WindowsOS
|| abi.binaryFormat() != Abi::PEFormat)
return false;
if (abi.osFlavor() == Abi::WindowsMSysFlavor
|| abi.osFlavor() == Abi::WindowsCEFlavor)
return false;
if (m_wordWidth && abi.wordWidth() != m_wordWidth)
return false;
return true;
}
// Find a CDB profile for debugging unknown processes.
// On a 64bit OS, prefer a 64bit debugger.
static Profile *findUniversalCdbProfile()
{
#ifdef Q_OS_WIN
if (Utils::winIs64BitSystem()) {
CdbMatcher matcher64(64);
if (Profile *cdb64Profile = ProfileManager::instance()->find(&matcher64))
return cdb64Profile;
}
#endif
CdbMatcher matcher;
return ProfileManager::instance()->find(&matcher);
}
private:
const char m_wordWidth;
};
void fillParameters(DebuggerStartParameters *sp, const Profile *profile /* = 0 */)
{
if (!profile)
profile = ProfileManager::instance()->defaultProfile();
if (!profile) {
// This code can only be reached when starting via the command
// (-debug pid or executable) without specifying a profile.
// Try to find a profile via ABI.
if (sp->executable.isEmpty()
&& (sp->startMode == AttachExternal || sp->startMode == AttachCrashedExternal)) {
sp->executable = executableForPid(sp->attachPID);
}
if (!sp->executable.isEmpty()) {
const QList<Abi> abis = Abi::abisOfBinary(Utils::FileName::fromString(sp->executable));
if (!abis.isEmpty()) {
AbiProfileMatcher matcher(abis);
profile = ProfileManager::instance()->find(&matcher);
if (!profile) {
CompatibleAbiProfileMatcher matcher(abis);
profile = ProfileManager::instance()->find(&matcher);
}
}
}
if (!profile)
profile = ProfileManager::instance()->defaultProfile();
}
sp->sysRoot = SysRootProfileInformation::sysRoot(profile).toString();
sp->debuggerCommand = DebuggerProfileInformation::debuggerCommand(profile).toString();
......@@ -1279,8 +1385,8 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
*errorMessage = msgParameterMissing(*it);
return false;
}
Profile *profile = 0;
DebuggerStartParameters sp;
fillParameters(&sp, ProfileManager::instance()->defaultProfile());
qulonglong pid = it->toULongLong();
if (pid) {
sp.startMode = AttachExternal;
......@@ -1318,11 +1424,11 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
sp.startMessage = tr("Attaching to core file %1.").arg(sp.coreFile);
}
else if (key == QLatin1String("profile")) {
Profile *profile = ProfileManager::instance()->find(Id(val));
fillParameters(&sp, profile);
profile = ProfileManager::instance()->find(Id(val));
}
}
}
fillParameters(&sp, profile);
if (sp.startMode == StartExternal) {
sp.displayName = tr("Executable file \"%1\"").arg(sp.executable);
sp.startMessage = tr("Debugging file %1.").arg(sp.executable);
......@@ -1342,7 +1448,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
return false;
}
DebuggerStartParameters sp;
fillParameters(&sp, 0);
fillParameters(&sp, CdbMatcher::findUniversalCdbProfile());
sp.startMode = AttachCrashedExternal;
sp.crashParameter = it->section(QLatin1Char(':'), 0, 0);
sp.attachPID = it->section(QLatin1Char(':'), 1, 1).toULongLong();
......@@ -1491,35 +1597,11 @@ void DebuggerPluginPrivate::attachCore()
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
struct RemoteCdbMatcher : ProfileMatcher
{
RemoteCdbMatcher() : m_hostAbi(Abi::hostAbi()) {}
bool matches(const Profile *profile) const
{
ToolChain *tc = ToolChainProfileInformation::toolChain(profile);
QTC_ASSERT(tc, return false);
Abi abi = tc->targetAbi();
if (abi.architecture() != m_hostAbi.architecture()
|| abi.os() != Abi::WindowsOS
|| abi.binaryFormat() != Abi::PEFormat
|| abi.wordWidth() != m_hostAbi.wordWidth())
return false;
if (abi.osFlavor() == Abi::WindowsMSysFlavor
|| abi.osFlavor() == Abi::WindowsCEFlavor)
return false;
return true;
}
Abi m_hostAbi;
};
void DebuggerPluginPrivate::startRemoteCdbSession()
{
const QString connectionKey = _("CdbRemoteConnection");
DebuggerStartParameters sp;
RemoteCdbMatcher matcher;
Profile *profile = ProfileManager::instance()->find(&matcher);
Profile *profile = CdbMatcher::findUniversalCdbProfile();
QTC_ASSERT(profile, return);
fillParameters(&sp, profile);
sp.startMode = AttachToRemoteServer;
......
......@@ -578,17 +578,12 @@ static DebuggerEngineType guessCppEngineTypeForAbi(const DebuggerStartParameters
return NoEngineType;
}
static DebuggerEngineType guessCppEngineType(const DebuggerStartParameters &sp, RunConfiguration *rc)
static DebuggerEngineType guessCppEngineType(const DebuggerStartParameters &sp)
{
if (rc) {
if (Target *target = rc->target()) {
Profile *profile = target->profile();
if (ToolChain *tc = ToolChainProfileInformation::toolChain(profile)) {
DebuggerEngineType et = guessCppEngineTypeForAbi(sp, tc->targetAbi());
if (et != NoEngineType)
return et;
}
}
if (sp.toolChainAbi.isValid()) {
const DebuggerEngineType et = guessCppEngineTypeForAbi(sp, sp.toolChainAbi);
if (et != NoEngineType)
return et;
}
#ifdef Q_OS_WIN
......@@ -628,23 +623,24 @@ static void fixupEngineTypes(DebuggerStartParameters &sp, RunConfiguration *rc)
if (rc) {
DebuggerRunConfigurationAspect *aspect = rc->debuggerAspect();
bool useCppDebugger = aspect->useCppDebugger();
bool useQmlDebugger = aspect->useQmlDebugger();
if (const Target *target = rc->target())
fillParameters(&sp, target->profile());
const bool useCppDebugger = aspect->useCppDebugger();
const bool useQmlDebugger = aspect->useQmlDebugger();
if (useQmlDebugger) {
if (useCppDebugger) {
sp.masterEngineType = QmlCppEngineType;
sp.firstSlaveEngineType = guessCppEngineType(sp, rc);
sp.firstSlaveEngineType = guessCppEngineType(sp);
sp.secondSlaveEngineType = QmlCppEngineType;
} else {
sp.masterEngineType = QmlEngineType;
}
} else {
sp.masterEngineType = guessCppEngineType(sp, rc);
sp.masterEngineType = guessCppEngineType(sp);
}
return;
}
sp.masterEngineType = guessCppEngineType(sp, rc);
sp.masterEngineType = guessCppEngineType(sp);
}
DebuggerRunControl *DebuggerRunControlFactory::doCreate
......
......@@ -140,7 +140,7 @@ public:
namespace Internal {
void fillParameters(DebuggerStartParameters *sp, ProjectExplorer::Profile *profile);
void fillParameters(DebuggerStartParameters *sp, const ProjectExplorer::Profile *profile = 0);
} // namespace Internal
} // namespace Debugger
......
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