summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-10-02 15:17:50 +0200
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-10-02 15:17:50 +0200
commit1fad39c9234839617470b3ff626d4e3f1311da1a (patch)
treeb23a88fdffdfe10cab12ae30a40e1f348df64e84
parent0cc5f14f299fa498ab66e6b54d496f3f18b42e6a (diff)
downloadqt-creator-1fad39c9234839617470b3ff626d4e3f1311da1a.tar.gz
CDB: Fix dumper regression
- Do not deref d-ptr when checking on QVariants of PODS - Make type/value fixing of dumper results more fine-grained - Allow children in expandPtrToDumpage (QWidget-Pointers) - Fix broken size cache (queuePrefix was empty) - Compile
-rw-r--r--share/qtcreator/gdbmacros/gdbmacros.cpp28
-rw-r--r--share/qtcreator/gdbmacros/test/main.cpp12
-rw-r--r--src/plugins/debugger/cdb/cdbstackframecontext.cpp35
-rw-r--r--src/plugins/debugger/cdb/cdbstacktracecontext.cpp3
-rw-r--r--src/plugins/debugger/watchutils.cpp3
5 files changed, 53 insertions, 28 deletions
diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 59049f2673..072a41c6b1 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -1177,7 +1177,7 @@ static void qDumpQAbstractItemModel(QDumper &d)
static void qDumpQByteArray(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const QByteArray &ba = *reinterpret_cast<const QByteArray *>(d.data);
if (!ba.isEmpty()) {
@@ -1461,7 +1461,7 @@ int hashOffset(bool optimizedIntKey, bool forKey, unsigned keySize, unsigned val
static void qDumpQHash(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const char *keyType = d.templateParameters[0];
const char *valueType = d.templateParameters[1];
@@ -1569,7 +1569,7 @@ static void qDumpQHashNode(QDumper &d)
#if USE_QT_GUI
static void qDumpQImage(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const QImage &im = *reinterpret_cast<const QImage *>(d.data);
d.beginItem("value");
d.put("(").put(im.width()).put("x").put(im.height()).put(")");
@@ -1611,7 +1611,7 @@ static void qDumpQImageData(QDumper &d)
static void qDumpQList(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
// This uses the knowledge that QList<T> has only a single member
// of type union { QListData p; QListData::Data *d; };
@@ -1691,7 +1691,7 @@ static void qDumpQList(QDumper &d)
static void qDumpQLinkedList(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
// This uses the knowledge that QLinkedList<T> has only a single member
// of type union { QLinkedListData *d; QLinkedListNode<T> *e; };
const QLinkedListData *ldata =
@@ -1817,7 +1817,7 @@ static void qDumpQMapNode(QDumper &d)
static void qDumpQMap(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
QMapData *h = *reinterpret_cast<QMapData *const*>(d.data);
const char *keyType = d.templateParameters[0];
const char *valueType = d.templateParameters[1];
@@ -1956,7 +1956,7 @@ static void qDumpQModelIndex(QDumper &d)
static void qDumpQObject(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
const QMetaObject *mo = ob->metaObject();
d.putItem("value", ob->objectName());
@@ -2206,7 +2206,7 @@ static void qDumpQVariant(QDumper &d, const QVariant *v)
static inline void qDumpQVariant(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(d.data);
qDumpQVariant(d, reinterpret_cast<const QVariant *>(d.data));
}
@@ -2832,7 +2832,7 @@ static void qDumpQSharedPointer(QDumper &d)
static void qDumpQString(QDumper &d)
{
- //qCheckAccess(deref(d.data));
+ //qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const QString &str = *reinterpret_cast<const QString *>(d.data);
const int size = str.size();
@@ -2857,7 +2857,7 @@ static void qDumpQString(QDumper &d)
static void qDumpQStringList(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
const QStringList &list = *reinterpret_cast<const QStringList *>(d.data);
int n = list.size();
if (n < 0)
@@ -2906,7 +2906,7 @@ static void qDumpQTextCodec(QDumper &d)
static void qDumpQVector(QDumper &d)
{
- qCheckAccess(deref(d.data));
+ qCheckAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
QVectorTypedData<int> *dummy = 0;
const unsigned typeddatasize = (char*)(&dummy->array) - (char*)dummy;
@@ -3810,7 +3810,11 @@ void *qDumpObjectData440(
d.exp = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
d.innerType = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
-
+#if 0
+ qDebug() << "data=" << d.data << "dumpChildren=" << d.dumpChildren
+ << " extra=" << d.extraInt[0] << d.extraInt[1] << d.extraInt[2] << d.extraInt[3]
+ << d.outerType << d.iname << d.exp << d.iname;
+#endif
handleProtocolVersion2and3(d);
}
diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp
index b6be579ab3..28dea56f76 100644
--- a/share/qtcreator/gdbmacros/test/main.cpp
+++ b/share/qtcreator/gdbmacros/test/main.cpp
@@ -227,7 +227,17 @@ static int dumpQMapQStringString()
static int dumpQVariant()
{
- QVariant test(QLatin1String("item"));
+ QVariant test = QLatin1String("item");
+ prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
+ qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
+ fputs(qDumpOutBuffer, stdout);
+ fputs("\n\n", stdout);
+ test = QVariant(int(42));
+ prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
+ qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
+ fputs(qDumpOutBuffer, stdout);
+ fputs("\n\n", stdout);
+ test = QVariant(double(3.141));
prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
fputs(qDumpOutBuffer, stdout);
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index 76d5e00cf8..93ab11d75e 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -128,21 +128,29 @@ WatchHandleDumperInserter::WatchHandleDumperInserter(WatchHandler *wh,
Q_ASSERT(m_hexNullPattern.isValid());
}
-
// Prevent recursion of the model by setting value and type
-static inline void fixDumperValueAndType(WatchData *wd, const WatchData *source = 0)
-{
- static const QString unknown = QCoreApplication::translate("CdbStackFrameContext", "<Unknown>");
- if (wd->isTypeNeeded() || wd->type.isEmpty()) {
- wd->setType(source ? source->type : unknown);
+static inline bool fixDumperType(WatchData *wd, const WatchData *source = 0)
+{
+ const bool missing = wd->isTypeNeeded() || wd->type.isEmpty();
+ if (missing) {
+ static const QString unknownType = QCoreApplication::translate("CdbStackFrameContext", "<Unknown Type>");
+ wd->setType(source ? source->type : unknownType);
}
- if (wd->isValueNeeded()) {
+ return missing;
+}
+
+static inline bool fixDumperValue(WatchData *wd, const WatchData *source = 0)
+{
+ const bool missing = wd->isValueNeeded();
+ if (missing) {
if (source && source->isValueKnown()) {
wd->setValue(source->value);
} else {
- wd->setValue(unknown);
+ static const QString unknownValue = QCoreApplication::translate("CdbStackFrameContext", "<Unknown Value>");
+ wd->setValue(unknownValue);
}
}
+ return missing;
}
// When querying an item, the queried item is sometimes returned in incomplete form.
@@ -160,7 +168,8 @@ static inline void fixDumperResult(const WatchData &source,
WatchData &returned = result->front();
if (returned.iname != source.iname)
return;
- fixDumperValueAndType(&returned, &source);
+ fixDumperType(&returned, &source);
+ fixDumperValue(&returned, &source);
// Indicate owner and known children
returned.source = OwnerDumper;
if (returned.isChildrenKnown() && returned.isHasChildrenKnown() && returned.hasChildren)
@@ -179,7 +188,9 @@ static inline void fixDumperResult(const WatchData &source,
it->source = OwnerDumper;
if (it->isChildrenKnown() && it->isHasChildrenKnown() && it->hasChildren)
it->source |= CdbStackFrameContext::ChildrenKnownBit;
- if (wd.addr.isEmpty() && wd.isSomethingNeeded()) {
+ // Cannot dump items with missing addresses or missing types
+ const bool typeFixed = fixDumperType(&wd); // Order of evaluation!
+ if ((wd.addr.isEmpty() && wd.isSomethingNeeded()) || typeFixed) {
wd.setHasChildren(false);
wd.setAllUnneeded();
} else {
@@ -188,8 +199,6 @@ static inline void fixDumperResult(const WatchData &source,
if (suppressGrandChildren && (wd.isChildrenNeeded() || wd.isHasChildrenNeeded()))
wd.setHasChildren(false);
}
- // <Out of scope value> have sometimes missing types. Kill recursion
- fixDumperValueAndType(&wd);
}
if (debugCDBWatchHandling)
debugWatchDataList(*result, "<fixDumperResult");
@@ -226,7 +235,7 @@ bool WatchHandleDumperInserter::expandPointerToDumpable(const WatchData &wd, QSt
const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(derefedWd, true, &m_dumperResult, errorMessage);
if (dr != CdbDumperHelper::DumpOk)
break;
- fixDumperResult(derefedWd, &m_dumperResult, true);
+ fixDumperResult(derefedWd, &m_dumperResult, false);
// Insert the pointer item with 1 additional child + its dumper results
// Note: formal arguments might already be expanded in the symbol group.
WatchData ptrWd = wd;
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index 6cdaf62709..40cd9776bc 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -86,7 +86,8 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
// Convert the DEBUG_STACK_FRAMEs to our StackFrame structure and populate the frames
WCHAR wszBuf[MAX_PATH];
for (ULONG i=0; i < frameCount; ++i) {
- StackFrame frame(i);
+ StackFrame frame;
+ frame.level = i;
const ULONG64 instructionOffset = m_cdbFrames[i].InstructionOffset;
if (i == 0)
m_instructionOffset = instructionOffset;
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 8208cb4fcf..a494c0d700 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -560,7 +560,7 @@ QString QtDumperHelper::toString(bool debug) const
str << "\nSize cache: ";
const SizeCache::const_iterator scend = m_sizeCache.constEnd();
for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) {
- str << ' ' << it.key() << '=' << it.value();
+ str << ' ' << it.key() << '=' << it.value() << '\n';
}
str << "\nExpression cache: (" << m_expressionCache.size() << ")\n";
const QMap<QString, QString>::const_iterator excend = m_expressionCache.constEnd();
@@ -888,6 +888,7 @@ void QtDumperHelper::setQClassPrefixes(const QString &qNamespace)
m_qListPrefix = qClassName(qNamespace, "QList");
m_qLinkedListPrefix = qClassName(qNamespace, "QLinkedList");
m_qVectorPrefix = qClassName(qNamespace, "QVector");
+ m_qQueuePrefix = qClassName(qNamespace, "QQueue");
}
static inline double getDumperVersion(const GdbMi &contents)