Merge remote-tracking branch 'origin/4.0'

Conflicts:
	src/plugins/debugger/watchdata.cpp
	src/plugins/debugger/watchdata.h
	src/shared/qbs

Change-Id: I19b338b316d9c4c046074eb85b3fec79e86e6c32
This commit is contained in:
Eike Ziller
2016-06-09 12:07:01 +02:00
10 changed files with 147 additions and 86 deletions

View File

@@ -652,7 +652,6 @@ void CdbEngine::setupInferior()
symbolPaths += symbolPath;
runCommand({".sympath \"" + symbolPaths.join(';') + '"', NoFlags});
runCommand({"!sym noisy", NoFlags}); // Show symbol load information.
runCommand({"sxn 0x4000001f", NoFlags}); // Do not break on WowX86 exceptions.
runCommand({"sxn ibp", NoFlags}); // Do not break on initial breakpoints.
runCommand({".asm source_line", NoFlags}); // Source line in assembly

View File

@@ -324,8 +324,11 @@ QString decodeItemHelper(const double &t)
return QString::number(t, 'g', 16);
}
class ArrayDataDecoder
{
public:
template <class T>
void decodeArrayHelper(WatchItem *item, const QString &rawData, int size, const QString &childType)
void decodeArrayHelper(int childSize)
{
const QByteArray ba = QByteArray::fromHex(rawData.toUtf8());
const T *p = (const T *) ba.data();
@@ -333,46 +336,49 @@ void decodeArrayHelper(WatchItem *item, const QString &rawData, int size, const
WatchItem *child = new WatchItem;
child->arrayIndex = i;
child->value = decodeItemHelper(p[i]);
child->size = size;
child->size = childSize;
child->type = childType;
child->address = addrbase + i * addrstep;
child->valueEditable = true;
child->setAllUnneeded();
item->appendChild(child);
}
}
static void decodeArrayData(WatchItem *item, const QString &rawData,
const DebuggerEncoding &encoding, const QString &childType)
void decode()
{
if (addrstep == 0)
addrstep = encoding.size;
switch (encoding.type) {
case DebuggerEncoding::HexEncodedSignedInteger:
switch (encoding.size) {
case 1:
return decodeArrayHelper<signed char>(item, rawData, encoding.size, childType);
return decodeArrayHelper<signed char>(encoding.size);
case 2:
return decodeArrayHelper<short>(item, rawData, encoding.size, childType);
return decodeArrayHelper<short>(encoding.size);
case 4:
return decodeArrayHelper<int>(item, rawData, encoding.size, childType);
return decodeArrayHelper<int>(encoding.size);
case 8:
return decodeArrayHelper<qint64>(item, rawData, encoding.size, childType);
return decodeArrayHelper<qint64>(encoding.size);
}
case DebuggerEncoding::HexEncodedUnsignedInteger:
switch (encoding.size) {
case 1:
return decodeArrayHelper<uchar>(item, rawData, encoding.size, childType);
return decodeArrayHelper<uchar>(encoding.size);
case 2:
return decodeArrayHelper<ushort>(item, rawData, encoding.size, childType);
return decodeArrayHelper<ushort>(encoding.size);
case 4:
return decodeArrayHelper<uint>(item, rawData, encoding.size, childType);
return decodeArrayHelper<uint>(encoding.size);
case 8:
return decodeArrayHelper<quint64>(item, rawData, encoding.size, childType);
return decodeArrayHelper<quint64>(encoding.size);
}
break;
case DebuggerEncoding::HexEncodedFloat:
switch (encoding.size) {
case 4:
return decodeArrayHelper<float>(item, rawData, encoding.size, childType);
return decodeArrayHelper<float>(encoding.size);
case 8:
return decodeArrayHelper<double>(item, rawData, encoding.size, childType);
return decodeArrayHelper<double>(encoding.size);
}
default:
break;
@@ -380,6 +386,14 @@ static void decodeArrayData(WatchItem *item, const QString &rawData,
qDebug() << "ENCODING ERROR: " << encoding.toString();
}
WatchItem *item;
QString rawData;
QString childType;
DebuggerEncoding encoding;
quint64 addrbase;
quint64 addrstep;
};
static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b)
{
auto aa = static_cast<const WatchItem *>(a);
@@ -473,9 +487,14 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
mi = input["arraydata"];
if (mi.isValid()) {
DebuggerEncoding encoding(input["arrayencoding"].data());
QString childType = input["childtype"].data();
decodeArrayData(this, mi.data(), encoding, childType);
ArrayDataDecoder decoder;
decoder.item = this;
decoder.rawData = mi.data();
decoder.childType = input["childtype"].data();
decoder.addrbase = input["addrbase"].toAddress();
decoder.addrstep = input["addrstep"].toAddress();
decoder.encoding = DebuggerEncoding(input["arrayencoding"].data());
decoder.decode();
} else {
const GdbMi children = input["children"];
if (children.isValid()) {
@@ -510,7 +529,8 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
child->iname = this->iname + '.' + nn;
if (addressStep) {
child->address = addressBase + i * addressStep;
child->exp = "*(" + gdbQuoteTypes(child->type) + "*)" + child->hexAddress();
child->exp = "*(" + gdbQuoteTypes(child->type) + "*)0x"
+ QString::number(child->address, 16);
}
QString key = subinput["key"].data();
if (!key.isEmpty())
@@ -581,8 +601,8 @@ QString WatchItem::toToolTip() const
}
formatToolTipRow(str, tr("Value"), val);
}
if (realAddress())
formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(realAddress()));
if (address)
formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(address));
if (origaddr)
formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr));
if (arrayIndex >= 0)
@@ -618,15 +638,6 @@ bool WatchItem::isInspect() const
return iname.startsWith("inspect.");
}
quint64 WatchItem::realAddress() const
{
if (arrayIndex >= 0) {
if (const WatchItem *p = parentItem())
return p->address + arrayIndex * size;
}
return address;
}
QString WatchItem::internalName() const
{
if (arrayIndex >= 0) {
@@ -647,7 +658,7 @@ QString WatchItem::expression() const
{
if (!exp.isEmpty())
return exp;
if (quint64 addr = realAddress()) {
if (quint64 addr = address) {
if (!type.isEmpty())
return QString("*(%1*)0x%2").arg(type).arg(addr, 0, 16);
}

View File

@@ -52,7 +52,6 @@ public:
QString expression() const;
QString realName() const;
quint64 realAddress() const;
QString internalName() const;
QString toToolTip() const;

View File

@@ -793,13 +793,13 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
<< MsvcToolChain::arm << MsvcToolChain::x86_arm << MsvcToolChain::amd64_arm
<< MsvcToolChain::ia64 << MsvcToolChain::x86_ia64;
foreach (const MsvcToolChain::Platform &platform, platforms) {
QString vcvarsBat = vcVarsBatFor(path, platform);
if (hostSupportsPlatform(platform) && QFileInfo(vcvarsBat).isFile()) {
const bool toolchainInstalled = QFileInfo(vcVarsBatFor(path, platform)).isFile();
if (hostSupportsPlatform(platform) && toolchainInstalled) {
results.append(findOrCreateToolChain(
alreadyKnown,
generateDisplayName(vsName, MsvcToolChain::VS, platform),
findAbiOfMsvc(MsvcToolChain::VS, platform, vsName),
vcvarsBat, platformName(platform),
vcvarsAllbat, platformName(platform),
ToolChain::AutoDetection));
}
}

View File

@@ -60,7 +60,7 @@ void QbsLogSink::sendMessages()
}
foreach (const QString &msg, toSend)
Core::MessageManager::write(msg);
Core::MessageManager::write(msg, Core::MessageManager::Silent);
}
void QbsLogSink::doPrintWarning(const qbs::ErrorInfo &warning)

View File

@@ -295,8 +295,8 @@ void BindingModel::updateExpression(int row)
{
BindingProperty bindingProperty = bindingPropertyForRow(row);
const QString sourceNode = data(index(row, SourceModelNodeRow)).toString();
const QString sourceProperty = data(index(row, SourcePropertyNameRow)).toString();
const QString sourceNode = data(index(row, SourceModelNodeRow)).toString().trimmed();
const QString sourceProperty = data(index(row, SourcePropertyNameRow)).toString().trimmed();
QString expression;
if (sourceProperty.isEmpty()) {

View File

@@ -98,6 +98,7 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
const WCHAR *key,
bool readWrite,
HKEY *keyHandle,
AccessMode mode,
QString *errorMessage)
{
Q_UNUSED(debuggerRegistryKeyC); // avoid warning from MinGW
@@ -105,6 +106,16 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
REGSAM accessRights = KEY_READ;
if (readWrite)
accessRights |= KEY_SET_VALUE;
switch (mode) {
case RegistryAccess::DefaultAccessMode:
break;
case RegistryAccess::Registry32Mode:
accessRights |= KEY_WOW64_32KEY;
break;
case RegistryAccess::Registry64Mode:
accessRights |= KEY_WOW64_64KEY;
break;
}
const LONG rc = RegOpenKeyEx(category, key, 0, accessRights, keyHandle);
if (rc != ERROR_SUCCESS) {
*errorMessage = msgFunctionFailed("RegOpenKeyEx", rc);

View File

@@ -36,6 +36,12 @@
namespace RegistryAccess {
enum AccessMode {
DefaultAccessMode,
Registry32Mode = 0x2, // Corresponds to QSettings::Registry32Format (5.7)
Registry64Mode = 0x4 // Corresponds to QSettings::Registry64Format (5.7)
};
static const char *debuggerApplicationFileC = "qtcdebugger";
static const WCHAR *debuggerRegistryKeyC = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
static const WCHAR *debuggerRegistryValueNameC = L"Debugger";
@@ -67,8 +73,12 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
const WCHAR *key,
bool readWrite,
HKEY *keyHandle,
AccessMode mode,
QString *errorMessage);
inline bool openRegistryKey(HKEY category, const WCHAR *key, bool readWrite, HKEY *keyHandle, QString *errorMessage)
{ return openRegistryKey(category, key, readWrite, keyHandle, DefaultAccessMode, errorMessage); }
QString debuggerCall(const QString &additionalOption = QString());
bool isRegistered(HKEY handle, const QString &call, QString *errorMessage, QString *oldDebugger = 0);

View File

@@ -70,6 +70,9 @@ static const char creatorBinaryC[] = "qtcreator.exe";
enum Mode { HelpMode, RegisterMode, UnregisterMode, PromptMode, ForceCreatorMode, ForceDefaultMode };
Mode optMode = PromptMode;
// WOW: Indicates registry key access mode:
// - Accessing 32bit using a 64bit built Qt Creator or,
// - Accessing 64bit using a 32bit built Qt Creator on 64bit Windows
bool optIsWow = false;
bool noguiMode = false;
unsigned long argProcessId = 0;
@@ -172,6 +175,14 @@ static void usage(const QString &binary, const QString &message = QString())
msgBox.exec();
}
static bool is64BitWindowsSystem() // Courtesy utils library
{
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
return systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64
|| systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64;
}
// ------- Registry helpers
static inline bool registryWriteBinaryKey(HKEY handle,
@@ -303,8 +314,15 @@ bool readDefaultDebugger(QString *defaultDebugger,
{
bool success = false;
HKEY handle;
if (openRegistryKey(HKEY_LOCAL_MACHINE, optIsWow ? debuggerWow32RegistryKeyC : debuggerRegistryKeyC,
false, &handle, errorMessage)) {
const RegistryAccess::AccessMode accessMode = optIsWow
#ifdef Q_OS_WIN64
? RegistryAccess::Registry32Mode
#else
? RegistryAccess::Registry64Mode
#endif
: RegistryAccess::DefaultAccessMode;
if (openRegistryKey(HKEY_LOCAL_MACHINE, debuggerRegistryKeyC, false, &handle, accessMode, errorMessage)) {
success = registryReadStringKey(handle, debuggerRegistryDefaultValueNameC,
defaultDebugger, errorMessage);
RegCloseKey(handle);
@@ -372,12 +390,13 @@ bool chooseDebugger(QString *errorMessage)
static bool registerDebuggerKey(const WCHAR *key,
const QString &call,
RegistryAccess::AccessMode access,
QString *errorMessage)
{
HKEY handle = 0;
bool success = false;
do {
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, errorMessage))
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, access, errorMessage))
break;
// Save old key, which might be missing
QString oldDebugger;
@@ -401,11 +420,16 @@ static bool registerDebuggerKey(const WCHAR *key,
bool install(QString *errorMessage)
{
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(), errorMessage))
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(), RegistryAccess::DefaultAccessMode, errorMessage))
return false;
#ifdef Q_OS_WIN64
if (!registerDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(QLatin1String("-wow")), errorMessage))
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry32Mode, errorMessage))
return false;
#else
if (is64BitWindowsSystem()) {
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry64Mode, errorMessage))
return false;
}
#endif
return true;
}
@@ -413,12 +437,13 @@ bool install(QString *errorMessage)
// Unregister helper: Restore the original debugger key
static bool unregisterDebuggerKey(const WCHAR *key,
const QString &call,
RegistryAccess::AccessMode access,
QString *errorMessage)
{
HKEY handle = 0;
bool success = false;
do {
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, errorMessage))
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, access, errorMessage))
break;
QString debugger;
if (!isRegistered(handle, call, errorMessage, &debugger) && !debugger.isEmpty()) {
@@ -448,12 +473,18 @@ static bool unregisterDebuggerKey(const WCHAR *key,
bool uninstall(QString *errorMessage)
{
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(), errorMessage))
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(), RegistryAccess::DefaultAccessMode, errorMessage))
return false;
#ifdef Q_OS_WIN64
if (!unregisterDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(QLatin1String("-wow")), errorMessage))
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry32Mode, errorMessage))
return false;
#else
if (is64BitWindowsSystem()) {
if (!unregisterDebuggerKey(debuggerRegistryKeyC, debuggerCall(QLatin1String("-wow")), RegistryAccess::Registry64Mode, errorMessage))
return false;
}
#endif
return true;
}