Commit ec0fb652 authored by hjk's avatar hjk

Debugger: Make more dumper work without debuginfo

Change-Id: I2ff23b81dc27be1052c36cffb7ad16dbea6fa339
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 00337585
......@@ -1320,6 +1320,7 @@ class Dumper:
self.formats = {}
self.useDynamicType = True
self.expandedINames = {}
self.childEventAddress = None
def __init__(self, args):
self.defaultInit()
......@@ -1571,18 +1572,36 @@ class Dumper:
return self.dereference(value.address)
def isQObject(self, value):
entryType = self.lookupType("int").pointer().pointer()
try:
vtable = createReferenceValue(value, value.address, entryType)
metaObjectEntry = vtable.dereference() # It's the first entry.
return str(metaObjectEntry).find("::metaObject() const") > 0
#if True:
vtable = self.dereference(long(value.address)) # + ptrSize
metaObjectEntry = self.dereference(vtable) # It's the first entry.
warn("MO: 0x%x " % metaObjectEntry)
s = gdb.execute("info symbol 0x%x" % metaObjectEntry, to_string=True)
warn("S: %s " % s)
#return s.find("::metaObject() const") > 0
return s.find("::metaObject() const") > 0 or s.find("10metaObjectEv") > 0
#return str(metaObjectEntry).find("::metaObject() const") > 0
except:
return False
def isQObject_B(self, value):
# Alternative: Check for specific values, like targeting the
# 'childEvent' member which is typically not overwritten, slot 8.
# entry = pointerValue(vtable) + 8 * ptrType.sizeof
# childEventEntry = createReferenceValue(value, entry, ptrType)
#warn("CHILDEVENT: %s " % childEventEntry)
# ~"Symbol \"Myns::QObject::childEvent(Myns::QChildEvent*)\" is a
# function at address 0xb70f691a.\n"
if self.childEventAddress == None:
try:
loc = gdb.execute("info address ::QObject::childEvent", to_string=True)
self.childEventAddress = long(loc[loc.rfind(' '):-2], 16)
except:
self.childEventAddress = 0
try:
vtable = self.dereference(long(value.address))
return self.childEventAddress == self.dereference(vtable + 8 * self.ptrSize())
except:
return False
def put(self, value):
self.output.append(value)
......
......@@ -51,11 +51,11 @@ def qByteArrayDataData(d, addr):
# Data:
# - QBasicAtomicInt ref;
# - int alloc, size;
# - [padding]
# - char *data;
# - char array[1];
alloc = d.extractInt(addr + intSize)
size = d.extractInt(addr + 2 * intSize)
data = addr + 3 * intSize + ptrSize
data = d.dereference(addr + 2 * intSize + ptrSize)
return data, size, alloc
def qByteArrayData(d, addr):
......@@ -168,6 +168,7 @@ def qPutQObjectNameValue(d, value):
objectName = d.dereference(extra + 5 * ptrSize)
data, size, alloc = d.stringData(objectName)
if size > 0:
str = d.readRawMemory(data, 2 * size)
d.putValue(str, Hex4EncodedLittleEndian, 1)
......@@ -398,9 +399,17 @@ def qdump__QTime(d, value):
# {sharedref(4), date(8), time(4+x)}
def qdump__QDateTime(d, value):
base = d.dereferenceValue(value)
mds = d.extractInt(base + d.ptrSize() + 8)
# QDateTimePrivate:
# - QAtomicInt ref;
# - [QDate date;] (+4)
# - - uint jd in Qt 4, qint64 in Qt 5
# - [QTime time;] (+4 + dateSize)
# - - uint mds;
# - Spec spec;
dateSize = 8 if d.qtVersion() >= 0x050000 else 4
mds = d.extractInt(base + 4 + dateSize)
if mds >= 0:
jd = d.extractInt(base + d.ptrSize())
jd = d.extractInt(base + 4)
d.putValue("%s/%s" % (jd, mds), JulianDateAndMillisecondsSinceMidnight)
d.putNumChild(1)
if d.isExpanded():
......@@ -412,12 +421,12 @@ def qdump__QDateTime(d, value):
qtdate += "DateFormat::" # FIXME: Bug?...
qttime += "TimeSpec::" # FIXME: Bug?...
d.putCallItem("toTime_t", value, "toTime_t")
d.putCallItem("toString", value, "toString", qtdate + "TextDate")
d.putCallItem("(ISO)", value, "toString", qtdate + "ISODate")
d.putCallItem("(SystemLocale)", value, "toString", qtdate + "SystemLocaleDate")
d.putCallItem("(Locale)", value, "toString", qtdate + "LocaleDate")
d.putCallItem("toUTC", value, "toTimeSpec", qttime + "UTC")
d.putCallItem("toLocalTime", value, "toTimeSpec", qttime + "LocalTime")
#d.putCallItem("toString", value, "toString", qtdate + "TextDate")
#d.putCallItem("(ISO)", value, "toString", qtdate + "ISODate")
#d.putCallItem("(SystemLocale)", value, "toString", qtdate + "SystemLocaleDate")
#d.putCallItem("(Locale)", value, "toString", qtdate + "LocaleDate")
#d.putCallItem("toUTC", value, "toTimeSpec", qttime + "UTC")
#d.putCallItem("toLocalTime", value, "toTimeSpec", qttime + "LocalTime")
else:
d.putValue("(invalid)")
d.putNumChild(0)
......@@ -1435,10 +1444,11 @@ def qdump__QObject(d, value):
# }
def qdump__QPixmap(d, value):
intPtrType = d.lookupType("int").pointer()
offset = (3 if d.qtVersion() >= 0x050000 else 2) * intPtrType.sizeof
base = d.createValue(d.addressOf(value) + offset, intPtrType)
d.putValue("(%dx%d)" % (base[1], base[2]))
offset = (3 if d.qtVersion() >= 0x050000 else 2) * d.ptrSize()
base = d.dereference(d.addressOf(value) + offset)
width = d.extractInt(base + 4)
height = d.extractInt(base + 8)
d.putValue("(%dx%d)" % (width, height))
d.putNumChild(0)
......
......@@ -545,9 +545,9 @@ private:
void tst_Dumpers::initTestCase()
{
m_debuggerBinary = qgetenv("QTC_DEBUGGER_PATH_FOR_TEST");
if (m_debuggerBinary.isEmpty())
m_debuggerBinary = "gdb";
qDebug() << "Debugger : " << m_debuggerBinary.constData();
m_debuggerEngine = DumpTestGdbEngine;
if (m_debuggerBinary.endsWith("cdb.exe"))
......@@ -559,6 +559,7 @@ void tst_Dumpers::initTestCase()
m_qmakeBinary = qgetenv("QTC_QMAKE_PATH_FOR_TEST");
if (m_qmakeBinary.isEmpty())
m_qmakeBinary = "qmake";
qDebug() << "QMake : " << m_qmakeBinary.constData();
Environment utilsEnv = Environment::systemEnvironment();
utilsEnv.appendOrSet(QLatin1String("QT_HASH_SEED"), QLatin1String("0"));
......@@ -574,8 +575,8 @@ void tst_Dumpers::initTestCase()
QByteArray output = debugger.readAllStandardOutput();
//qDebug() << "stdout: " << output;
m_usePython = !output.contains("Python scripting is not supported in this copy of GDB");
qDebug() << (m_usePython ? "Python is available" : "Python is not available");
qDebug() << "Dumper dir: " << DUMPERDIR;
qDebug() << "Python : " << (m_usePython ? "ok" : "*** not ok ***");
qDebug() << "Dumper dir : " << DUMPERDIR;
QString version = QString::fromLocal8Bit(output);
int pos1 = version.indexOf(QLatin1String("&\"show version\\n"));
......@@ -587,7 +588,7 @@ void tst_Dumpers::initTestCase()
version = version.mid(pos1, pos2 - pos1);
extractGdbVersion(version, &m_gdbVersion,
&m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb);
qDebug() << "Gdb version " << m_gdbVersion;
qDebug() << "Gdb version : " << m_gdbVersion;
} else if (m_debuggerEngine == DumpTestCdbEngine) {
QByteArray envBat = qgetenv("QTC_MSVC_ENV_BAT");
QMap <QString, QString> envPairs;
......@@ -1116,20 +1117,23 @@ void tst_Dumpers::dumper_data()
QTest::newRow("QDateTime0")
<< Data("#include <QDateTime>\n",
"QDateTime date;\n")
"QDateTime date;\n"
"unused(&date);\n")
% CoreProfile()
% Check("date", "(invalid)", "@QDateTime");
QTest::newRow("QDateTime1")
<< Data("#include <QDateTime>\n",
"QDateTime date(QDate(1980, 1, 1), QTime(13, 15, 32), Qt::UTC);\n")
"QDateTime date(QDate(1980, 1, 1), QTime(13, 15, 32), Qt::UTC);\n"
"unused(&date);\n")
% CoreProfile()
% Check("date", "Tue Jan 1 13:15:32 1980", "@QDateTime")
% Check("date.(ISO)", "\"1980-01-01T13:15:32Z\"", "@QString")
% CheckType("date.(Locale)", "@QString")
% CheckType("date.(SystemLocale)", "@QString")
% Check("date.toString", "\"Tue Jan 1 13:15:32 1980\"", "@QString")
% Check("date.toUTC", "Tue Jan 1 13:15:32 1980", "@QDateTime");
//% Check("date.(ISO)", "\"1980-01-01T13:15:32Z\"", "@QString")
//% CheckType("date.(Locale)", "@QString")
//% CheckType("date.(SystemLocale)", "@QString")
//% Check("date.toString", "\"Tue Jan 1 13:15:32 1980\"", "@QString")
//% Check("date.toUTC", "Tue Jan 1 13:15:32 1980", "@QDateTime"
% Check("date.toTime_t", "315580532", "unsigned int");
#ifdef Q_OS_WIN
QByteArray tempDir = "\"C:/Program Files\"";
......@@ -3111,16 +3115,17 @@ void tst_Dumpers::dumper_data()
% Check("anc", "1", "int");
QTest::newRow("QThread1")
<< Data("#include <QThread>\n",
<< Data("#include <QThread>\n"
"struct Thread : QThread\n"
"{\n"
" virtual ~Thread() {}\n"
" void run()\n"
" {\n"
" if (m_id == 3)\n"
" breakHere();\n"
" }\n"
" int m_id;\n"
"};\n"
"};\n",
"const int N = 14;\n"
"Thread thread[N];\n"
"for (int i = 0; i != N; ++i) {\n"
......@@ -3128,9 +3133,10 @@ void tst_Dumpers::dumper_data()
" thread[i].setObjectName(\"This is thread #\" + QString::number(i));\n"
" thread[i].start();\n"
"}\n")
% CheckType("this", "Thread")
% Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread")
% Check("this.@1.@1", "[@QObject]", "\"This is thread #3\"", "@QObject");
% CoreProfile()
% CheckType("this", "Thread")
% Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread")
% Check("this.@1.@1", "[@QObject]", "\"This is thread #3\"", "@QObject");
QTest::newRow("QVariant1")
<< Data("#include <QVariant>\n",
......@@ -3249,6 +3255,7 @@ void tst_Dumpers::dumper_data()
"QVariant var;\n"
"var.setValue(my);\n"
"breakHere();\n")
% CoreProfile()
% Check("my", "<2 items>", "MyType")
% Check("my.0", "[0]", "", "@QMapNode<unsigned int, @QStringList>")
% Check("my.0.key", "1", "unsigned int")
......@@ -3297,6 +3304,7 @@ void tst_Dumpers::dumper_data()
"vl.append(QVariant(21));\n"
"vl.append(QVariant(22));\n"
"vl.append(QVariant(\"2Some String\"));\n")
% CoreProfile()
% Check("vl", "<6 items>", "@QVariantList")
% CheckType("vl.0", "[0]", "@QVariant (int)")
% CheckType("vl.2", "[2]", "@QVariant (QString)");
......@@ -3310,6 +3318,7 @@ void tst_Dumpers::dumper_data()
"vm[\"d\"] = QVariant(21);\n"
"vm[\"e\"] = QVariant(22);\n"
"vm[\"f\"] = QVariant(\"2Some String\");\n")
% CoreProfile()
% Check("vm", "<6 items>", "@QVariantMap")
% Check("vm.0", "[0]", "", "@QMapNode<@QString, @QVariant>")
% Check("vm.0.key", Value4("\"a\""), "@QString")
......@@ -3318,15 +3327,16 @@ void tst_Dumpers::dumper_data()
% Check("vm.0.value", Value5("2"), "@QVariant (int)")
% Check("vm.5", "[5]", "", "@QMapNode<@QString, @QVariant>")
% Check("vm.5.key", Value4("\"f\""), "@QString")
% Check("vm.5.value", Value4("\"2Some String\""), "@QVariant (@QString)")
% Check("vm.5.value", Value4("\"2Some String\""), "@QVariant (QString)")
% Check("vm.5.key", Value5("\"f\""), "@QString")
% Check("vm.5.value", Value5("\"2Some String\""), "@QVariant (@QString)");
% Check("vm.5.value", Value5("\"2Some String\""), "@QVariant (QString)");
QTest::newRow("QVectorIntBig")
<< Data("#include <QVector>\n",
"QVector<int> vec(10000);\n"
"for (int i = 0; i != vec.size(); ++i)\n"
" vec[i] = i * i;\n")
% CoreProfile()
% Check("vec", "<10000 items>", "@QVector<int>")
% Check("vec.0", "[0]", "0", "int")
% Check("vec.1999", "[1999]", "3996001", "int");
......@@ -3336,6 +3346,7 @@ void tst_Dumpers::dumper_data()
"QVector<Foo> vec;\n"
"vec.append(1);\n"
"vec.append(2);\n")
% CoreProfile()
% Check("vec", "<2 items>", "@QVector<Foo>")
% Check("vec.0", "[0]", "", "Foo")
% Check("vec.0.a", "1", "int")
......@@ -3348,7 +3359,8 @@ void tst_Dumpers::dumper_data()
"FooVector vec;\n"
"vec.append(1);\n"
"vec.append(2);\n")
% Check("vec", "<2 items>", "@FooVector")
% CoreProfile()
% Check("vec", "<2 items>", "FooVector")
% Check("vec.0", "[0]", "", "Foo")
% Check("vec.0.a", "1", "int")
% Check("vec.1", "[1]", "", "Foo")
......@@ -4025,7 +4037,7 @@ void tst_Dumpers::dumper_data()
"boost::optional<QStringList> sl0, sl;\n"
"sl = (QStringList() << \"xxx\" << \"yyy\");\n"
"sl.get().append(\"zzz\");\n")
% Check("sl", "<3 items>", "boost::optional<QStringList>");
% Check("sl", "<3 items>", "boost::optional<@QStringList>");
QTest::newRow("BoostSharedPtr")
<< Data("#include <QStringList>\n"
......
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