forked from qt-creator/qt-creator
debugger: show cdb vtable pointer in hex
Change-Id: I8deb537ce837e54315b0f0a64897363f70344137 Reviewed-by: Friedemann Kleint Task-number: QTCREATORBUG-5381 Reviewed-on: http://codereview.qt.nokia.com/1405 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
@@ -762,6 +762,14 @@ static void fixValue(const std::string &type, std::wstring *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip a vtable "0x13f37b7c8 module!Class::`vftable'" to a plain pointer.
|
||||||
|
if (SymbolGroupValue::isVTableType(type)) {
|
||||||
|
const std::wstring::size_type blankPos = value->find(L' ', 2);
|
||||||
|
if (blankPos != std::wstring::npos)
|
||||||
|
value->erase(blankPos, value->size() - blankPos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Pointers: fix '0x00000000`00000AD class bla' ... to "0xAD", but leave
|
// Pointers: fix '0x00000000`00000AD class bla' ... to "0xAD", but leave
|
||||||
// 'const char *' values as is ('0x00000000`00000AD "hallo").
|
// 'const char *' values as is ('0x00000000`00000AD "hallo").
|
||||||
if (!type.empty() && type.at(type.size() - 1) == L'*') {
|
if (!type.empty() && type.at(type.size() - 1) == L'*') {
|
||||||
|
|||||||
@@ -417,6 +417,13 @@ unsigned SymbolGroupValue::isPointerType(const std::string &t)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return number of characters to strip for pointer type
|
||||||
|
bool SymbolGroupValue::isVTableType(const std::string &t)
|
||||||
|
{
|
||||||
|
const char vtableTypeC[] = "__fptr() [";
|
||||||
|
return t.compare(0, sizeof(vtableTypeC) - 1, vtableTypeC) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
// add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
|
// add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
|
||||||
std::string SymbolGroupValue::pointerType(const std::string &type)
|
std::string SymbolGroupValue::pointerType(const std::string &type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public:
|
|||||||
static std::string moduleOfType(const std::string &type);
|
static std::string moduleOfType(const std::string &type);
|
||||||
// pointer type, return number of characters to strip
|
// pointer type, return number of characters to strip
|
||||||
static unsigned isPointerType(const std::string &);
|
static unsigned isPointerType(const std::string &);
|
||||||
|
static bool isVTableType(const std::string &t);
|
||||||
// add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
|
// add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
|
||||||
static std::string pointerType(const std::string &type);
|
static std::string pointerType(const std::string &type);
|
||||||
// Symbol Name/(Expression) of a pointed-to instance ('Foo' at 0x10') ==> '*(Foo *)0x10'
|
// Symbol Name/(Expression) of a pointed-to instance ('Foo' at 0x10') ==> '*(Foo *)0x10'
|
||||||
|
|||||||
@@ -68,6 +68,13 @@ bool isPointerType(const QByteArray &type)
|
|||||||
return type.endsWith('*') || type.endsWith("* const");
|
return type.endsWith('*') || type.endsWith("* const");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVTablePointer(const QByteArray &type)
|
||||||
|
{
|
||||||
|
// FIXME: That is cdb only.
|
||||||
|
// But no user type can be named like this, so this is safe.
|
||||||
|
return type.startsWith("__fptr()");
|
||||||
|
}
|
||||||
|
|
||||||
bool isCharPointerType(const QByteArray &type)
|
bool isCharPointerType(const QByteArray &type)
|
||||||
{
|
{
|
||||||
return type == "char *" || type == "const char *" || type == "char const *";
|
return type == "char *" || type == "const char *" || type == "char const *";
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ static inline QString formattedValue(const WatchData &data, int format)
|
|||||||
return reformatInteger(data.value.toLongLong(), format);
|
return reformatInteger(data.value.toLongLong(), format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPointerType(data.type)) {
|
if (!isPointerType(data.type) && !isVTablePointer(data.type)) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
qulonglong integer = data.value.toULongLong(&ok, 0);
|
qulonglong integer = data.value.toULongLong(&ok, 0);
|
||||||
if (ok)
|
if (ok)
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ bool hasLetterOrNumber(const QString &exp);
|
|||||||
bool hasSideEffects(const QString &exp);
|
bool hasSideEffects(const QString &exp);
|
||||||
bool isKeyWord(const QString &exp);
|
bool isKeyWord(const QString &exp);
|
||||||
bool isPointerType(const QByteArray &type);
|
bool isPointerType(const QByteArray &type);
|
||||||
|
bool isVTablePointer(const QByteArray &type);
|
||||||
bool isCharPointerType(const QByteArray &type);
|
bool isCharPointerType(const QByteArray &type);
|
||||||
bool startsWithDigit(const QString &str);
|
bool startsWithDigit(const QString &str);
|
||||||
QByteArray stripPointerType(QByteArray type);
|
QByteArray stripPointerType(QByteArray type);
|
||||||
|
|||||||
Reference in New Issue
Block a user