From b295aec1ad51576d7590c7ccdc2708f7ffceaec3 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Thu, 25 Jun 2009 15:00:57 +0200 Subject: [PATCH] debugger: fix several small issues in the dumper code Fix typo in QChar helper. Add a auto tests for some of the dumpers. Make the dumpers compilable for Qt < 4.5 for better regression tests. Make manual tests compile with Qt < 4.5. --- share/qtcreator/gdbmacros/gdbmacros.cpp | 104 +++++++------ share/qtcreator/gdbmacros/gdbmacros.h | 46 ++++++ src/plugins/debugger/watchhandler.cpp | 5 +- tests/auto/debugger/debugger.pro | 8 +- tests/auto/debugger/main.cpp | 192 +++++++++++++++++++++++- tests/manual/gdbdebugger/simple/app.cpp | 8 + 6 files changed, 310 insertions(+), 53 deletions(-) create mode 100644 share/qtcreator/gdbmacros/gdbmacros.h diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index fa55c4d7bc8..207f1c7d15d 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -44,11 +44,14 @@ #include <QtCore/QObject> #include <QtCore/QPointer> #include <QtCore/QString> -#include <QtCore/QSharedPointer> -#include <QtCore/QSharedDataPointer> #include <QtCore/QTextCodec> #include <QtCore/QVector> + +#if QT_VERSION >= 0x040500 +#include <QtCore/QSharedPointer> +#include <QtCore/QSharedDataPointer> #include <QtCore/QWeakPointer> +#endif int qtGhVersion = QT_VERSION; @@ -180,6 +183,9 @@ struct Sender { QObject *sender; int signal; int ref; }; int method; uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking QBasicAtomicPointer<int> argumentTypes; + //senders linked list + //Connection *next; + //Connection **prev; }; typedef QList<Connection *> ConnectionList; @@ -191,11 +197,11 @@ struct Sender { QObject *sender; int signal; int ref; }; int signalAt(const SenderList &l, int i) { return l.at(i)->method; } #endif -class QObjectPrivate : public QObjectData +class ObjectPrivate : public QObjectData { public: - QObjectPrivate() {} - virtual ~QObjectPrivate() {} + ObjectPrivate() {} + virtual ~ObjectPrivate() {} QList<QObject *> pendingChildInsertedEvents; void *threadData; @@ -222,10 +228,18 @@ QT_END_NAMESPACE // This can be mangled typenames of nested templates, each char-by-char // comma-separated integer list... -Q_DECL_EXPORT char qDumpInBuffer[10000]; - // The output buffer. -Q_DECL_EXPORT char qDumpOutBuffer[1000000]; +#ifdef MACROSDEBUG + Q_DECL_EXPORT char xDumpInBuffer[10000]; + Q_DECL_EXPORT char xDumpOutBuffer[1000000]; + #define inBuffer xDumpInBuffer + #define outBuffer xDumpOutBuffer +#else + Q_DECL_EXPORT char qDumpInBuffer[10000]; + Q_DECL_EXPORT char qDumpOutBuffer[1000000]; + #define inBuffer qDumpInBuffer + #define outBuffer qDumpOutBuffer +#endif namespace { @@ -476,15 +490,15 @@ QDumper::QDumper() { success = false; full = false; - qDumpOutBuffer[0] = 'f'; // marks output as 'wrong' + outBuffer[0] = 'f'; // marks output as 'wrong' pos = 1; } QDumper::~QDumper() { - qDumpOutBuffer[pos++] = '\0'; + outBuffer[pos++] = '\0'; if (success) - qDumpOutBuffer[0] = (full ? '+' : 't'); + outBuffer[0] = (full ? '+' : 't'); } void QDumper::setupTemplateParameters() @@ -510,49 +524,49 @@ void QDumper::setupTemplateParameters() QDumper &QDumper::operator<<(unsigned long long c) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%llu", c); + pos += sprintf(outBuffer + pos, "%llu", c); return *this; } QDumper &QDumper::operator<<(unsigned long c) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%lu", c); + pos += sprintf(outBuffer + pos, "%lu", c); return *this; } QDumper &QDumper::operator<<(float d) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%f", d); + pos += sprintf(outBuffer + pos, "%f", d); return *this; } QDumper &QDumper::operator<<(double d) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%f", d); + pos += sprintf(outBuffer + pos, "%f", d); return *this; } QDumper &QDumper::operator<<(unsigned int i) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%u", i); + pos += sprintf(outBuffer + pos, "%u", i); return *this; } QDumper &QDumper::operator<<(long c) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%ld", c); + pos += sprintf(outBuffer + pos, "%ld", c); return *this; } QDumper &QDumper::operator<<(int i) { checkFill(); - pos += sprintf(qDumpOutBuffer + pos, "%d", i); + pos += sprintf(outBuffer + pos, "%d", i); return *this; } @@ -576,7 +590,7 @@ QDumper &QDumper::operator<<(const void *p) void QDumper::checkFill() { - if (pos >= int(sizeof(qDumpOutBuffer)) - 100) + if (pos >= int(sizeof(outBuffer)) - 100) full = true; } @@ -584,14 +598,14 @@ void QDumper::put(char c) { checkFill(); if (!full) - qDumpOutBuffer[pos++] = c; + outBuffer[pos++] = c; } void QDumper::addCommaIfNeeded() { if (pos == 0) return; - char c = qDumpOutBuffer[pos - 1]; + char c = outBuffer[pos - 1]; if (c == '}' || c == '"' || c == ']') put(','); } @@ -736,8 +750,8 @@ void QDumper::putEllipsis() #define DUMPUNKNOWN_MESSAGE "<internal error>" static void qDumpUnknown(QDumper &d, const char *why = 0) { - P(d, "iname", d.iname); - P(d, "addr", d.data); + //P(d, "iname", d.iname); + //P(d, "addr", d.data); if (!why) why = DUMPUNKNOWN_MESSAGE; P(d, "value", why); @@ -792,7 +806,7 @@ static void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr if (isEqual(type, "QChar")) { d.addCommaIfNeeded(); QChar c = *(QChar *)addr; - char str[] = "'?', usc=\0"; + char str[] = "'?', ucs=\0"; if (c.isPrint() && c.unicode() < 127) str[1] = char(c.unicode()); P(d, field, str << c.unicode()); @@ -1007,7 +1021,7 @@ static void qDumpQChar(QDumper &d) { d.addCommaIfNeeded(); QChar c = *(QChar *)d.data; - char str[] = "'?', usc=\0"; + char str[] = "'?', ucs=\0"; if (c.isPrint() && c.unicode() < 127) str[1] = char(c.unicode()); P(d, "value", str << c.unicode()); @@ -1740,7 +1754,7 @@ static void qDumpQObject(QDumper &d) #if 0 d.beginHash(); P(d, "name", "senders"); - P(d, "exp", "(*(class '"NS"QObjectPrivate'*)" << dfunc(ob) << ")->senders"); + P(d, "exp", "(*(class '"NS"ObjectPrivate'*)" << dfunc(ob) << ")->senders"); P(d, "type", NS"QList<"NS"QObjectPrivateSender>"); d.endHash(); #endif @@ -1862,7 +1876,7 @@ const char * qConnectionTypes[] ={ static const ConnectionList &qConnectionList(const QObject *ob, int signalNumber) { static const ConnectionList emptyList; - const QObjectPrivate *p = reinterpret_cast<const QObjectPrivate *>(dfunc(ob)); + const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob)); if (!p->connectionLists) return emptyList; typedef QVector<ConnectionList> ConnLists; @@ -1963,7 +1977,7 @@ static void qDumpQObjectSlot(QDumper &d) d << ",children=["; int numchild = 0; const QObject *ob = reinterpret_cast<const QObject *>(d.data); - const QObjectPrivate *p = reinterpret_cast<const QObjectPrivate *>(dfunc(ob)); + const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob)); for (int s = 0; s != p->senders.size(); ++s) { const QObject *sender = senderAt(p->senders, s); int signal = signalAt(p->senders, s); @@ -2003,7 +2017,7 @@ static void qDumpQObjectSlotList(QDumper &d) { const QObject *ob = reinterpret_cast<const QObject *>(d.data); #if QT_VERSION >= 0x040400 - const QObjectPrivate *p = reinterpret_cast<const QObjectPrivate *>(dfunc(ob)); + const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob)); #endif const QMetaObject *mo = ob->metaObject(); @@ -2011,11 +2025,10 @@ static void qDumpQObjectSlotList(QDumper &d) for (int i = mo->methodCount(); --i >= 0; ) count += (mo->method(i).methodType() == QMetaMethod::Slot); - P(d, "addr", d.data); P(d, "numchild", count); -#if QT_VERSION >= 0x040400 if (d.dumpChildren) { d << ",children=["; +#if QT_VERSION >= 0x040400 for (int i = 0; i != mo->methodCount(); ++i) { const QMetaMethod & method = mo->method(i); if (method.methodType() == QMetaMethod::Slot) { @@ -2042,9 +2055,9 @@ static void qDumpQObjectSlotList(QDumper &d) d.endHash(); } } +#endif d << "]"; } -#endif d.disarm(); } @@ -2105,6 +2118,7 @@ static void qDumpQSet(QDumper &d) d.disarm(); } +#if QT_VERSION >= 0x040500 static void qDumpQSharedPointer(QDumper &d) { const QSharedPointer<int> &ptr = @@ -2143,6 +2157,7 @@ static void qDumpQSharedPointer(QDumper &d) } d.disarm(); } +#endif // QT_VERSION >= 0x040500 static void qDumpQString(QDumper &d) { @@ -2342,6 +2357,7 @@ static void qDumpQVector(QDumper &d) d.disarm(); } +#if QT_VERSION >= 0x040500 static void qDumpQWeakPointer(QDumper &d) { const int v = sizeof(void *); @@ -2379,6 +2395,7 @@ static void qDumpQWeakPointer(QDumper &d) } d.disarm(); } +#endif // QT_VERSION >= 0x040500 static void qDumpStdList(QDumper &d) { @@ -2645,7 +2662,6 @@ static void qDumpStdVectorBool(QDumper &d) static void handleProtocolVersion2and3(QDumper & d) { - if (!d.outertype[0]) { qDumpUnknown(d); return; @@ -2772,8 +2788,10 @@ static void handleProtocolVersion2and3(QDumper & d) case 'S': if (isEqual(type, "QSet")) qDumpQSet(d); + #if QT_VERSION >= 0x040500 else if (isEqual(type, "QSharedPointer")) qDumpQSharedPointer(d); + #endif else if (isEqual(type, "QString")) qDumpQString(d); else if (isEqual(type, "QStringList")) @@ -2810,8 +2828,11 @@ static void handleProtocolVersion2and3(QDumper & d) qDumpQVector(d); break; case 'W': + #if QT_VERSION >= 0x040500 if (isEqual(type, "QWeakPointer")) qDumpQWeakPointer(d); + #endif + break; } if (!d.success) @@ -2832,11 +2853,7 @@ void *qDumpObjectData440( int protocolVersion, int token, void *data, -#ifdef Q_CC_MSVC // CDB cannot handle boolean parameters int dumpChildren, -#else - bool dumpChildren, -#endif int extraInt0, int extraInt1, int extraInt2, @@ -2856,6 +2873,7 @@ void *qDumpObjectData440( "\""NS"QAbstractItem\"," "\""NS"QAbstractItemModel\"," "\""NS"QByteArray\"," + "\""NS"QChar\"," "\""NS"QDateTime\"," "\""NS"QDir\"," "\""NS"QFile\"," @@ -2870,9 +2888,6 @@ void *qDumpObjectData440( "\""NS"QMap\"," "\""NS"QMapNode\"," "\""NS"QModelIndex\"," -#if QT_VERSION >= 0x040500 - "\""NS"QMultiMap\"," -#endif "\""NS"QObject\"," "\""NS"QObjectMethodList\"," // hack to get nested properties display "\""NS"QObjectPropertyList\"," @@ -2882,13 +2897,16 @@ void *qDumpObjectData440( "\""NS"QObjectSlotList\"," // << "\""NS"QRegion\"," "\""NS"QSet\"," - "\""NS"QSharedPointer\"," "\""NS"QString\"," "\""NS"QStringList\"," "\""NS"QTextCodec\"," "\""NS"QVariant\"," "\""NS"QVector\"," +#if QT_VERSION >= 0x040500 + "\""NS"QMultiMap\"," + "\""NS"QSharedPointer\"," "\""NS"QWeakPointer\"," +#endif #if USE_QT_GUI "\""NS"QWidget\"," #endif @@ -2947,7 +2965,7 @@ void *qDumpObjectData440( d.extraInt[2] = extraInt2; d.extraInt[3] = extraInt3; - const char *inbuffer = qDumpInBuffer; + const char *inbuffer = inBuffer; d.outertype = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer; d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer; d.exp = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer; @@ -2960,5 +2978,5 @@ void *qDumpObjectData440( else { qDebug() << "Unsupported protocol version" << protocolVersion; } - return qDumpOutBuffer; + return outBuffer; } diff --git a/share/qtcreator/gdbmacros/gdbmacros.h b/share/qtcreator/gdbmacros/gdbmacros.h new file mode 100644 index 00000000000..8372d160e0c --- /dev/null +++ b/share/qtcreator/gdbmacros/gdbmacros.h @@ -0,0 +1,46 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef GDBMACROS_H +#define GDBMACROS_H + +#ifdef MACROSDEBUG +Q_DECL_EXPORT extern char xDumpInBuffer[]; +Q_DECL_EXPORT extern char xDumpOutBuffer[]; +#else +Q_DECL_EXPORT extern char qDumpInBuffer[]; +Q_DECL_EXPORT extern char qDumpOutBuffer[]; +#endif + +extern "C" Q_DECL_EXPORT +void *qDumpObjectData440(int protocolVersion, int token, void *data, + int dumpChildren, int extraInt0, int extraInt1, int extraInt2, int extraInt3); + + +#endif // GDBMACROS_H diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 57cb69c0964..c482a5f668e 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -186,7 +186,7 @@ void WatchData::setType(const QString &str) setHasChildren(false); } -void WatchData::setAddress(const QString & str) +void WatchData::setAddress(const QString &str) { addr = str; } @@ -196,8 +196,7 @@ WatchData WatchData::pointerChildPlaceHolder() const WatchData data1; data1.iname = iname + QLatin1String(".*"); data1.name = QLatin1Char('*') + name; - data1 -.exp = QLatin1String("(*(") + exp + QLatin1String("))"); + data1.exp = QLatin1String("(*(") + exp + QLatin1String("))"); data1.type = stripPointerType(type); data1.setValueNeeded(); return data1; diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro index a7001a24d4d..c3a9f0b966d 100644 --- a/tests/auto/debugger/debugger.pro +++ b/tests/auto/debugger/debugger.pro @@ -2,12 +2,16 @@ QT = core testlib DEBUGGERDIR = ../../../src/plugins/debugger -UTILSDIR = ../../../src/libs +UTILSDIR = ../../../src/libs +MACROSDIR = ../../../share/qtcreator/gdbmacros SOURCES += \ $$DEBUGGERDIR/gdb/gdbmi.cpp \ $$DEBUGGERDIR/tcf/json.cpp \ + $$MACROSDIR/gdbmacros.cpp \ main.cpp \ -INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR +DEFINES += MACROSDEBUG + +INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR $$MACROSDIR diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index 86ecf8cb03a..677eff1071a 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -1,13 +1,27 @@ -#include "gdb/gdbmi.h" -#include "tcf/json.h" - #include <QtCore/QObject> #include <QtCore/QProcess> #include <QtCore/QFileInfo> #include <QtTest/QtTest> + +#include <QtCore/private/qobject_p.h> + //#include <QtTest/qtest_gui.h> +#include "gdb/gdbmi.h" +#include "tcf/json.h" +#include "gdbmacros.h" + + +#undef NS +#ifdef QT_NAMESPACE +# define STRINGIFY0(s) #s +# define STRINGIFY1(s) STRINGIFY0(s) +# define NS STRINGIFY1(QT_NAMESPACE) "::" +#else +# define NS "" +#endif + using namespace Debugger; using namespace Debugger::Internal; @@ -98,6 +112,12 @@ private slots: void niceType(); void niceType_data(); + void dumperCompatibility(); + void dumpQHash(); + void dumpQObject(); + void dumpQString(); + void dumpStdVector(); + public slots: void runQtc(); @@ -154,6 +174,10 @@ void tst_Debugger::infoBreak() QCOMPARE(re.cap(4), QString("124")); } +// +// type simplification +// + static QString chopConst(QString type) { while (1) { @@ -175,7 +199,6 @@ QString niceType(QString type) { type.replace('*', '@'); - int pos; for (int i = 0; i < 10; ++i) { int start = type.indexOf("std::allocator<"); if (start == -1) @@ -299,6 +322,166 @@ void tst_Debugger::niceType_data() << "std::map<const char*, Foo>"; } +// +// Dumpers +// + +static void testDumper(QByteArray expected0, void *data, QByteArray outertype, + bool dumpChildren, QByteArray innertype = "", QByteArray exp = "", + int extraInt0 = 0, int extraInt1 = 0, int extraInt2 = 0, int extraInt3 = 0) +{ + sprintf(xDumpInBuffer, "%s%c%s%c%s%c%s%c%s%c", + outertype.data(), 0, "iname", 0, exp.data(), 0, + innertype.data(), 0, "iname", 0); + void *res = qDumpObjectData440(2, 42, data, dumpChildren, + extraInt0, extraInt1, extraInt2, extraInt3); + QString expected(expected0); + char buf[100]; + sprintf(buf, "%p", data); + if (!expected.startsWith('t') && !expected.startsWith('f')) + expected = "tiname='$I',addr='$A'," + expected; + expected.replace("$I", "iname"); + expected.replace("$T", QByteArray(outertype)); + expected.replace("$A", QByteArray(buf)); + expected.replace('\'', '"'); + QString actual____ = QString::fromLatin1(xDumpOutBuffer); + actual____.replace('\'', '"'); + QCOMPARE(res, xDumpOutBuffer); + if (actual____ != expected) { + QStringList l1 = actual____.split(","); + QStringList l2 = expected.split(","); + for (int i = 0; i < l1.size() && i < l2.size(); ++i) { + if (l1.at(i) == l2.at(i)) + qDebug() << "== " << l1.at(i); + else + qDebug() << "!= " << l1.at(i) << l2.at(i); + } + if (l1.size() != l2.size()) + qDebug() << "!= size: " << l1.size() << l2.size(); + } + QCOMPARE(actual____, expected); +} + +QByteArray str(const void *p) +{ + char buf[100]; + sprintf(buf, "%p", p); + return buf; +} + +static const void *deref(const void *p) +{ + return *reinterpret_cast<const char* const*>(p); +} + +void tst_Debugger::dumperCompatibility() +{ +} + +void tst_Debugger::dumpQHash() +{ + QHash<QString, QList<int> > hash; + hash.insert("Hallo", QList<int>()); + hash.insert("Welt", QList<int>() << 1); + hash.insert("!", QList<int>() << 1 << 2); + hash.insert("!", QList<int>() << 1 << 2); +} + +void tst_Debugger::dumpQObject() +{ + QObject parent; + testDumper("value='',valueencoded='2',type='$T',displayedtype='QObject'," + "numchild='4'", + &parent, NS"QObject", false); + testDumper("value='',valueencoded='2',type='$T',displayedtype='QObject'," + "numchild='4',children=[" + "{name='properties',exp='*(class '$T'*)$A',type='$TPropertyList'," + "value='<1 items>',numchild='1'}," + "{name='signals',exp='*(class '$T'*)$A',type='$TSignalList'," + "value='<2 items>',numchild='2'}," + "{name='slots',exp='*(class '$T'*)$A',type='$TSlotList'," + "value='<2 items>',numchild='2'}," + "{name='parent',value='0x0',type='$T *'}," + "{name='className',value='QObject',type='',numchild='0'}]", + &parent, NS"QObject", true); + + testDumper("numchild='2',children=[{name='2',value='deleteLater()'," + "numchild='0',exp='*(class 'QObject'*)$A',type='QObjectSlot'}," + "{name='3',value='_q_reregisterTimers(void*)'," + "numchild='0',exp='*(class 'QObject'*)$A',type='QObjectSlot'}]", + &parent, NS"QObjectSlotList", true); + + parent.setObjectName("A Parent"); + testDumper("value='QQAgAFAAYQByAGUAbgB0AA==',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4'", + &parent, NS"QObject", false); + QObject child(&parent); + testDumper("value='',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4'", + &child, NS"QObject", false); + child.setObjectName("A Child"); + QByteArray ba ="value='QQAgAEMAaABpAGwAZAA=',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4',children=[" + "{name='properties',exp='*(class '$T'*)$A',type='$TPropertyList'," + "value='<1 items>',numchild='1'}," + "{name='signals',exp='*(class '$T'*)$A',type='$TSignalList'," + "value='<2 items>',numchild='2'}," + "{name='slots',exp='*(class '$T'*)$A',type='$TSlotList'," + "value='<2 items>',numchild='2'}," + "{name='parent',addr='" + str(&parent) + "'," + "value='QQAgAFAAYQByAGUAbgB0AA==',valueencoded='2',type='$T'," + "displayedtype='QObject'}," + "{name='className',value='QObject',type='',numchild='0'}]"; + testDumper(ba, &child, NS"QObject", true); + QObject::connect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); + testDumper(ba, &child, NS"QObject", true); + QObject::disconnect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); + testDumper(ba, &child, NS"QObject", true); + child.setObjectName("A renamed Child"); + testDumper("value='QQAgAHIAZQBuAGEAbQBlAGQAIABDAGgAaQBsAGQA',valueencoded='2'," + "type='$T',displayedtype='QObject',numchild='4'", + &child, NS"QObject", false); +} + +void tst_Debugger::dumpQString() +{ + QString s; + testDumper("value='',valueencoded='2',type='$T',numchild='0'", + &s, NS"QString", false); + s = "abc"; + testDumper("value='YQBiAGMA',valueencoded='2',type='$T',numchild='0'", + &s, NS"QString", false); +} + +void tst_Debugger::dumpStdVector() +{ + std::vector<std::list<int> *> vector; + QByteArray inner = "std::list<int> *"; + QByteArray innerp = "std::list<int>"; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'", + &vector, "std::vector", false, inner, "", sizeof(std::list<int> *)); + std::list<int> list; + vector.push_back(new std::list<int>(list)); + testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + "children=[{name='0',addr='" + str(deref(&vector[0])) + "'," + "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}]", + &vector, "std::vector", true, inner, "", sizeof(std::list<int> *)); + vector.push_back(0); + list.push_back(45); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "children=[{name='0',addr='" + str(deref(&vector[0])) + "'," + "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}," + "{name='1',addr='" + str(&vector[1]) + "'," + "type='" + innerp + "',value='<null>',numchild='0'}]", + &vector, "std::vector", true, inner, "", sizeof(std::list<int> *)); + vector.push_back(new std::list<int>(list)); + vector.push_back(0); +} + +// +// Creator +// + void tst_Debugger::readStandardOutput() { qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput()); @@ -338,7 +521,6 @@ int main(int argc, char *argv[]) QCoreApplication app(argc, argv); QStringList args = app.arguments(); - if (args.size() == 2 && args.at(1) == "--run-debuggee") { runDebuggee(); app.exec(); diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp index a3a004cfc52..705e5787420 100644 --- a/tests/manual/gdbdebugger/simple/app.cpp +++ b/tests/manual/gdbdebugger/simple/app.cpp @@ -39,7 +39,9 @@ #include <QtCore/QThread> #include <QtCore/QVariant> #include <QtCore/QVector> +#if QT_VERSION >= 0x040500 #include <QtCore/QSharedPointer> +#endif #include <QtGui/QApplication> #include <QtGui/QAction> @@ -523,6 +525,7 @@ void testQSet() //hash.insert(ptr); } +#if QT_VERSION >= 0x040500 class EmployeeData : public QSharedData { public: @@ -580,6 +583,7 @@ void testQSharedPointer() QWeakPointer<QString> wptr2 = wptr; QWeakPointer<QString> wptr3 = wptr; } +#endif void stringRefTest(const QString &refstring) { @@ -1131,6 +1135,8 @@ void testObject1() parent.setObjectName("A Parent"); QObject child(&parent); child.setObjectName("A Child"); + QObject::connect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); + QObject::disconnect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); child.setObjectName("A renamed Child"); } @@ -1198,7 +1204,9 @@ int main(int argc, char *argv[]) testQMultiMap(); testQString(); testQSet(); + #if QT_VERSION >= 0x040500 testQSharedPointer(); + #endif testQStringList(); testStruct(); //testThreads(); -- GitLab