diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index fdcbfad0f83370de09f8e06b95410c8aaf47af70..b3f054ffbb2ea639cb6cc418bbb6d3cd7d962f25 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -32,7 +32,7 @@ // this relies on contents copied from qobject_p.h #define PRIVATE_OBJECT_ALLOWED 1 -#ifdef HAS_QOBJECT_P_H +#ifdef HAS_QOBJECT_P_H // Detected by qmake # include <QtCore/private/qobject_p.h> #endif #include <QtCore/QDateTime> @@ -149,7 +149,7 @@ int qtGhVersion = QT_VERSION; # define NSY "" #endif -#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H +#if PRIVATE_OBJECT_ALLOWED && !defined(HAS_QOBJECT_P_H) #if defined(QT_BEGIN_NAMESPACE) QT_BEGIN_NAMESPACE @@ -292,8 +292,8 @@ static bool startsWith(const char *s, const char *t) // On Windows, try to be less crash-prone by checking memory using WinAPI #ifdef Q_OS_WIN -# define qCheckAccess(d) if (IsBadReadPtr(d, 1)) return; do { qProvokeSegFaultHelper = *(char*)d; } while (0) -# define qCheckPointer(d) if (d && IsBadReadPtr(d, 1)) return; do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) +# define qCheckAccess(d) do { if (IsBadReadPtr(d, 1)) return; qProvokeSegFaultHelper = *(char*)d; } while (0) +# define qCheckPointer(d) do { if (d && IsBadReadPtr(d, 1)) return; if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) #else # define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) @@ -2252,7 +2252,14 @@ static void qDumpQWeakPointer(QDumper &d) static void qDumpStdList(QDumper &d) { const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data); - const void *p = d.data; +#ifdef Q_CC_MSVC + const int size = static_cast<int>(list.size()); + if (size < 0) + return; + if (size) + qCheckAccess(list.begin().operator ->()); +#else + const void *p = d.data; qCheckAccess(p); p = deref(p); qCheckAccess(p); @@ -2264,7 +2271,7 @@ static void qDumpStdList(QDumper &d) qCheckAccess(p); p = deref(addOffset(p, sizeof(void*))); qCheckAccess(p); - +#endif int nn = 0; std::list<int>::const_iterator it = list.begin(); for (; nn < 101 && it != list.end(); ++nn, ++it) @@ -2447,7 +2454,7 @@ static void qDumpStdWString(QDumper &d) } static void qDumpStdVector(QDumper &d) -{ +{ // Correct type would be something like: // std::_Vector_base<int,std::allocator<int, std::allocator<int> >>::_Vector_impl struct VectorImpl { @@ -2455,8 +2462,13 @@ static void qDumpStdVector(QDumper &d) char *finish; char *end_of_storage; }; +#ifdef Q_CC_MSVC + // Pointers are at end of the structure + const char * vcp = static_cast<const char *>(d.data); + const VectorImpl *v = reinterpret_cast<const VectorImpl *>(vcp + sizeof(std::vector<int>) - sizeof(VectorImpl)); +#else const VectorImpl *v = static_cast<const VectorImpl *>(d.data); - +#endif // Try to provoke segfaults early to prevent the frontend // from asking for unavailable child details int nn = (v->finish - v->start) / d.extraInt[0]; diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp index f760e40aa980b9329349d5cf47a5fb65bd2cec3a..fcb6d9061cd4af4849731845ccfd1dcdbe478131 100644 --- a/share/qtcreator/gdbmacros/test/main.cpp +++ b/share/qtcreator/gdbmacros/test/main.cpp @@ -30,11 +30,11 @@ #include <QtCore/QStringList> #include <QtCore/QVector> #include <QtCore/QTimer> -#include <QtCore/private/qobject_p.h> #include <string> #include <list> #include <vector> +#include <set> #include <stdio.h> #include <string.h> @@ -204,19 +204,36 @@ static int dumpStdStringVector() return 0; } +static int dumpStdIntSet() +{ + std::set<int> test; + test.insert(1); + test.insert(2); + prepareInBuffer("std::set", "local.intset", "local.intset", "int"); + qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdStringSet() +{ + std::set<std::string> test; + test.insert("item1"); + test.insert("item2"); + prepareInBuffer("std::set", "local.stringset", "local.stringset", "std::string"); + qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} static int dumpQObject() { + // Requires the childOffset to be know, but that is not critical QTimer t; - QObjectPrivate *tp = reinterpret_cast<QObjectPrivate *>(&t); -#ifdef KNOWS_OFFSET - const int childOffset = (char*)&tp->children - (char*)tp; -#else - const int childOffset = 0; -#endif - printf("Qt version %s Child offset: %d\n", QT_VERSION_STR, childOffset); prepareInBuffer("QObject", "local.qobject", "local.qobject", ""); - qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0); + qDumpObjectData440(2, 42, &t, 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; @@ -256,6 +273,10 @@ int main(int argc, char *argv[]) dumpStdIntVector(); if (!qstrcmp(arg, "vector<string>")) dumpStdStringVector(); + if (!qstrcmp(arg, "set<int>")) + dumpStdIntSet(); + if (!qstrcmp(arg, "set<string>")) + dumpStdStringSet(); if (!qstrcmp(arg, "QObject")) dumpQObject(); } diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 407ada9cadfbb74c7421917257817a11f5fa1086..812442a323896035a84c03c235772bf6143e3680 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -455,7 +455,7 @@ QDebug operator<<(QDebug in, const QtDumperResult &d) const QtDumperResult::Child &c = d.children.at(i); nospace << " #" << i << " addr=" << c.address << " disabled=" << c.valuedisabled - << " type=" << c.type + << " type=" << c.type << " exp=" << c.exp << " name=" << c.name << " encoded=" << c.valueEncoded << " value=" << c.value << "childcount=" << c.childCount << '\n'; @@ -1377,6 +1377,8 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r) // Sanity if (r->childCount < r->children.size()) r->childCount = r->children.size(); + if (debug) + qDebug() << '\n' << data << *r; return true; }