forked from qt-creator/qt-creator
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:
@@ -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
|
||||
|
||||
@@ -324,61 +324,75 @@ QString decodeItemHelper(const double &t)
|
||||
return QString::number(t, 'g', 16);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void decodeArrayHelper(WatchItem *item, const QString &rawData, int size, const QString &childType)
|
||||
class ArrayDataDecoder
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
void decodeArrayHelper(int childSize)
|
||||
{
|
||||
const QByteArray ba = QByteArray::fromHex(rawData.toUtf8());
|
||||
const T *p = (const T *) ba.data();
|
||||
for (int i = 0, n = ba.size() / sizeof(T); i < n; ++i) {
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ public:
|
||||
|
||||
QString expression() const;
|
||||
QString realName() const;
|
||||
quint64 realAddress() const;
|
||||
QString internalName() const;
|
||||
QString toToolTip() const;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user