forked from qt-creator/qt-creator
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user