Qt6Natvis any1?
-
Hi,
I also searched for a Qt6 natvis but still did't found one, so I tried to adapt the existing one from Qt5. Many datatypes have changed to be much more easier for debugging now and I could make working the most relvant ones like QString, QByteArray, QList (including QStringList) and all the simple types.
A small problem is within QMap which need to be double expanded (first the map itself, than the std::map below) to show members, because I found no way to directly address the used std::map.
And QVariant has a very dirty hack I don't know if it's working everywhere and with every new Qt-Build. The problem is, that I could not found a simple access to a type-variable, so I used the accessible 'packedType' and extract the least 10 bit, which seems to be usable as a constant TypeID. Unfortunately this ID doesn't correspond with any type ID from QMetaType. For each unidentified QVariant-Type I print this id as value in the debugger. You can create an own rule using this ID (see conditions at the end of the code as example). Also for QVariant, there is no separation for shared object, so using sharing is expected not to show anything usable.
NOTE: not all classes have been adapted, especially the Pointer classes are untouched, but left in the file
<?xml version="1.0" encoding="utf-8"?> <!-- Qt6.natvis based on the Qt5.natvis provided by Qt-VS-Addon adaptations regarding Qt6 for most of simple datatypes, as well as QMap and QList types --> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="QPoint"> <AlternativeType Name="QPointF"/> <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString> <Expand> <Item Name="[x]">xp</Item> <Item Name="[y]">yp</Item> </Expand> </Type> <Type Name="QRect"> <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString> <Expand> <Item Name="[x]">x1</Item> <Item Name="[y]">y1</Item> <Item Name="[width]">x2 - x1 + 1</Item> <Item Name="[height]">y2 - y1 + 1</Item> </Expand> </Type> <Type Name="QRectF"> <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString> <Expand> <Item Name="[x]">xp</Item> <Item Name="[y]">yp</Item> <Item Name="[width]">w</Item> <Item Name="[height]">h</Item> </Expand> </Type> <Type Name="QSize"> <AlternativeType Name="QSizeF"/> <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString> <Expand> <Item Name="[width]">wd</Item> <Item Name="[height]">ht</Item> </Expand> </Type> <Type Name="QLine"> <AlternativeType Name="QLineF"/> <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString> <Expand> <Synthetic Name="[start point]"> <DisplayString>{pt1}</DisplayString> <Expand> <ExpandedItem>pt1</ExpandedItem> </Expand> </Synthetic> <Synthetic Name="[end point]"> <DisplayString>{pt2}</DisplayString> <Expand> <ExpandedItem>pt2</ExpandedItem> </Expand> </Synthetic> </Expand> </Type> <Type Name="QPolygon"> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <Item Name="[referenced]">d->ref.atomic._q_value</Item> <ArrayItems> <Size>d->size</Size> <ValuePointer>(QPoint*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name="QPolygonF"> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <Item Name="[closed]"> d->size > 0 && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp) && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp) </Item> <Item Name="[referenced]">d->ref.atomic._q_value</Item> <ArrayItems> <Size>d->size</Size> <ValuePointer>(QPointF*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name ="QVector2D"> <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString> <Expand> <Item Name="[x]">xp</Item> <Item Name="[y]">yp</Item> </Expand> </Type> <Type Name ="QVector3D"> <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString> <Expand> <Item Name="[x]">xp</Item> <Item Name="[y]">yp</Item> <Item Name="[z]">zp</Item> </Expand> </Type> <Type Name ="QVector4D"> <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString> <Expand> <Item Name="[x]">xp</Item> <Item Name="[y]">yp</Item> <Item Name="[z]">zp</Item> <Item Name="[w]">wp</Item> </Expand> </Type> <Type Name ="QMatrix"> <DisplayString> {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }} </DisplayString> <Expand> <Item Name="[m11]">_m11</Item> <Item Name="[m12]">_m12</Item> <Item Name="[m21]">_m21</Item> <Item Name="[m22]">_m22</Item> <Item Name="[dx]">_dx</Item> <Item Name="[dy]">_dy</Item> </Expand> </Type> <Type Name ="QMatrix4x4"> <DisplayString> {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }} </DisplayString> <Expand> <Item Name="[m11]">m[0][0]</Item> <Item Name="[m12]">m[1][0]</Item> <Item Name="[m13]">m[2][0]</Item> <Item Name="[m14]">m[3][0]</Item> <Item Name="[m21]">m[0][1]</Item> <Item Name="[m22]">m[1][1]</Item> <Item Name="[m23]">m[2][1]</Item> <Item Name="[m24]">m[3][1]</Item> <Item Name="[m31]">m[0][2]</Item> <Item Name="[m32]">m[1][2]</Item> <Item Name="[m33]">m[2][2]</Item> <Item Name="[m34]">m[3][2]</Item> <Item Name="[m41]">m[0][3]</Item> <Item Name="[m42]">m[1][3]</Item> <Item Name="[m43]">m[2][3]</Item> <Item Name="[m44]">m[3][3]</Item> </Expand> </Type> <Type Name="QSizePolicy"> <DisplayString> {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }} </DisplayString> <Expand> <Synthetic Name="[vertical policy]"> <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)}</DisplayString> </Synthetic> <Synthetic Name="[horizontal policy]"> <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)}</DisplayString> </Synthetic> <Synthetic Name="[control type]"> <DisplayString>QSizePolicy::ControlType::{ControlType(1 << bits.ctype)}</DisplayString> </Synthetic> <Synthetic Name="[expanding directions]"> <DisplayString Condition="(static_cast<Policy>(bits.verPolicy) & ExpandFlag)"> Qt::Vertical (2) </DisplayString> <DisplayString Condition="(static_cast<Policy>(bits.horPolicy) & ExpandFlag)"> Qt::Horizontal (1) </DisplayString> </Synthetic> <Item Name="[vertical stretch]">static_cast<int>(bits.verStretch)</Item> <Item Name="[horizontal stretch]">static_cast<int>(bits.horStretch)</Item> <Item Name="[has height for width]">bits.hfw == 1</Item> <Item Name="[has width for height]">bits.wfh == 1</Item> </Expand> </Type> <Type Name="QChar"> <DisplayString>{ucs,c}</DisplayString> <StringView>ucs,c</StringView> <Expand> <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item> <Item Name="[unicode]">ucs,c</Item> </Expand> </Type> <Type Name="QString"> <DisplayString>{d.ptr,sub}</DisplayString> <StringView>d.ptr</StringView> <Expand> <Item Name="[size]">d.size</Item> <Item Name="[text]">d.ptr,sub</Item> </Expand> </Type> <Type Name="QByteArray"> <DisplayString>{d.ptr,sb}</DisplayString> <StringView>d.ptr</StringView> <Expand> <Item Name="[size]">d.size</Item> <Item Name="[text]">d.ptr,sb</Item> </Expand> </Type> <Type Name="QBitArray"> <DisplayString>{{ size = {(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)} }}</DisplayString> <Expand> <Item Name="[referenced]">d.d->ref.atomic._q_value</Item> <IndexListItems> <Size>(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)</Size> <ValueNode> (*(reinterpret_cast<const unsigned char*>((reinterpret_cast<char*>(d.d)) + d.d->offset) + 1 + ($i >> 3)) & (1 << ($i & 7))) != 0 </ValueNode> </IndexListItems> </Expand> </Type> <Type Name="QVarLengthArray<*>"> <AlternativeType Name="QVarLengthArray<*, int>"/> <DisplayString>{{ size = {s} }}</DisplayString> <Expand> <Item Name="[capacity]">a</Item> <ArrayItems> <Size>s</Size> <ValuePointer>ptr</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name="QDate"> <DisplayString>{{ julian day = {jd} }}</DisplayString> <Expand></Expand> </Type> <Type Name="QTime"> <DisplayString>{mds/ 3600000}:{mds%3600000/60000}:{mds/1000%60}.{mds%1000}</DisplayString> <Expand> <Item Name="[hour]" Condition="(mds / 3600000) == 1">mds / 3600000, d</Item> <Item Name="[hours]" Condition="(mds / 3600000) != 1">mds / 3600000, d</Item> <Item Name="[minute]" Condition="((mds % 3600000) / 60000) == 1">(mds % 3600000) / 60000, d</Item> <Item Name="[minutes]" Condition="((mds % 3600000) / 60000) != 1">(mds % 3600000) / 60000, d</Item> <Item Name="[second]" Condition="((mds / 1000) % 60) == 1">(mds / 1000) % 60, d</Item> <Item Name="[seconds]" Condition="((mds / 1000) % 60) != 1">(mds / 1000) % 60, d</Item> <Item Name="[millisecond]" Condition="(mds % 1000) == 1">mds % 1000, d</Item> <Item Name="[milliseconds]" Condition="(mds % 1000) != 1">mds % 1000, d</Item> </Expand> </Type> <Type Name="QRegularExpression"> <DisplayString>{d.pattern}</DisplayString> </Type> <Type Name="QSharedData"> <Expand> <Item Name="[referenced]">ref._q_value</Item> </Expand> </Type> <Type Name="QSharedPointer<*>"> <DisplayString>strong reference to shared pointer of type {"$T1"}</DisplayString> <Expand> <Item Name="[is null]">value == 0</Item> <Item Name="[weak referenced]">d->weakref._q_value</Item> <Item Name="[strong referenced]">d->strongref._q_value</Item> </Expand> </Type> <Type Name="QSharedDataPointer<*>"> <DisplayString>pointer to implicit shared object of type {"$T1"}</DisplayString> <Expand> <ExpandedItem>d</ExpandedItem> </Expand> </Type> <Type Name="QExplicitlySharedDataPointer<*>"> <DisplayString>pointer to explicit shared object of type {"$T1"}</DisplayString> <Expand> <ExpandedItem>d</ExpandedItem> </Expand> </Type> <Type Name="QPointer<*>"> <DisplayString>guarded pointer to subclass of QObject of type {"$T1"}</DisplayString> <Expand> <Item Name="[is null]">wp.d == 0 || wp.d->strongref._q_value == 0 || wp.value == 0</Item> </Expand> </Type> <Type Name="QWeakPointer<*>"> <DisplayString>weak reference to shared pointer of type {"$T1"}</DisplayString> <Expand> <Item Name="[is null]">d == 0 || d->strongref._q_value == 0 || value == 0</Item> <Item Name="[weak referenced]">d->weakref._q_value</Item> <Item Name="[strong referenced]">d->strongref._q_value</Item> </Expand> </Type> <Type Name="QScopedPointer<*>"> <DisplayString>scoped pointer to a dynamically allocated object of type {"$T1"}</DisplayString> <Expand> <Item Name="[is null]">!d</Item> </Expand> </Type> <Type Name="QScopedArrayPointer<*>"> <DisplayString>scoped pointer to dynamically allocated array of objects of type {"$T1"}</DisplayString> <Expand> <Item Name="[is null]">!d</Item> </Expand> </Type> <Type Name="QPair<*,*>"> <DisplayString>({first}, {second})</DisplayString> <Expand> <Item Name="[first]">first</Item> <Item Name="[second]">second</Item> </Expand> </Type> <Type Name="QVector<*>"> <AlternativeType Name="QStack<*>"></AlternativeType> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <Item Name="[referenced]">d->ref.atomic._q_value</Item> <ArrayItems> <Size>d->size</Size> <ValuePointer>($T1*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer> </ArrayItems> </Expand> </Type> <!--Type Name="QList<*>"> <AlternativeType Name="QStringList"></AlternativeType> <AlternativeType Name="QQueue<*>"></AlternativeType> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <Item Name="[referenced]">d.ptr</Item> <IndexListItems> <Size>d.size</Size> <ValueNode>*reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*)) ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v : reinterpret_cast<$T1*>(d->array + d->begin + $i)) </ValueNode> </IndexListItems> </Expand> </Type--> <Type Name="QStringList"> <DisplayString>{{ size = {d.size} }}</DisplayString> <Expand> <IndexListItems> <Size>d.size</Size> <ValueNode> d.ptr + $i,na </ValueNode> </IndexListItems> </Expand> </Type> <Type Name="QList<*>"> <AlternativeType Name="QQueue<*>"></AlternativeType> <DisplayString>{{ size = {d.size} }}</DisplayString> <Expand> <IndexListItems> <Size>d.size</Size> <ValueNode> d.ptr + $i,na </ValueNode> </IndexListItems> </Expand> </Type> <Type Name="QLinkedList<*>"> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <Item Name="[referenced]">d->ref.atomic._q_value</Item> <LinkedListItems> <Size>d->size</Size> <HeadPointer>d->n</HeadPointer> <NextPointer>n</NextPointer> <ValueNode>(*(QLinkedListNode<$T1>*)this).t</ValueNode> </LinkedListItems> </Expand> </Type> <Type Name="QMapNode<*,*>"> <DisplayString>({key}, {value})</DisplayString> <Expand> <Item Name="[key]">key</Item> <Item Name="[value]">value</Item> </Expand> </Type> <Type Name="QMap<*,*>"> <AlternativeType Name="QMultiMap<*,*>"/> <DisplayString>{{ size = {d.d->m} }}</DisplayString> <Expand> <Item Name="[std::map]">d.d->m</Item> </Expand> </Type> <Type Name="QHashNode<*,*>"> <DisplayString Condition="next == 0">(empty)</DisplayString> <DisplayString Condition="next != 0">({key}, {value})</DisplayString> <Expand> <Item Name="[key]" Condition="next != 0">key</Item> <Item Name="[value]" Condition="next != 0">value</Item> <Item Name="[next]" Condition="next != 0">next</Item> </Expand> </Type> <Type Name="QHash<*,*>"> <AlternativeType Name="QMultiHash<*,*>"/> <DisplayString>{{ size = {d->size} }}</DisplayString> <Expand> <ArrayItems IncludeView="buckets"> <Size>d->numBuckets</Size> <ValuePointer>reinterpret_cast<Node **>(d->buckets)</ValuePointer> </ArrayItems> <CustomListItems ExcludeView="buckets"> <Variable Name="n" InitialValue="d->numBuckets"/> <Variable Name="bucket" InitialValue="d->buckets"/> <Variable Name="node" InitialValue="d->buckets[0]"/> <Variable Name="keyValuePair" InitialValue="reinterpret_cast<Node *>(0)"/> <Size>d->size</Size> <Loop> <Break Condition="n == 0"/> <Exec>node = *(bucket++)</Exec> <Exec>--n</Exec> <Loop> <Break Condition="!node || !node->next"/> <Exec>keyValuePair = reinterpret_cast<Node *>(node)</Exec> <Item Name="[{keyValuePair->key}]">keyValuePair->value</Item> <Exec>node = node->next</Exec> </Loop> </Loop> </CustomListItems> </Expand> </Type> <Type Name="QHashNode<*,QHashDummyValue>"> <DisplayString Condition="next == 0">(empty)</DisplayString> <DisplayString Condition="next != 0">({key})</DisplayString> <Expand> <Item Name="[key]" Condition="next != 0">key</Item> </Expand> </Type> <Type Name="QSet<*>"> <DisplayString>{{ size = {q_hash.d->size} }}</DisplayString> <Expand> <ExpandedItem>q_hash</ExpandedItem> </Expand> </Type> <Type Name="QCache<*,*>::Node"> <DisplayString>({*keyPtr}, {*t})</DisplayString> <Expand> <Item Name="[key]">*keyPtr</Item> <Item Name="[value]">*t</Item> </Expand> </Type> <Type Name="QColor"> <DisplayString>rgba = {ct.argb.red/257}, {ct.argb.green/257}, {ct.argb.blue/257}, {ct.argb.alpha/257}</DisplayString> <Expand> <Item Name="red">ct.argb.red/257</Item> <Item Name="green">ct.argb.green/257</Item> <Item Name="blue">ct.argb.blue/257</Item> <Item Name="alpha">ct.argb.alpha/257</Item> </Expand> </Type> <Type Name="QCache<*,*>"> <DisplayString>{{ size = {hash.d->size} }}</DisplayString> <Expand> <Item Name="[max coast]">mx</Item> <Item Name="[total coast]">total</Item> <Item Name="[referenced]">hash.d->ref.atomic._q_value</Item> <LinkedListItems> <Size>hash.d->size</Size> <HeadPointer>f</HeadPointer> <NextPointer>n</NextPointer> <ValueNode>*((Node*)this)</ValueNode> </LinkedListItems> </Expand> </Type> <Type Name="QVariant"> <DisplayString Condition="(d.is_null == 1)">NULL</DisplayString> <DisplayString Condition="(d.packedType&1023) == 0">{*((QStringList*)(d.data.data))} (QStringList)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 72">{*((QString*)(d.data.data))} (string)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 108">{*((qint64*)(d.data.data))} (i64)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 144">{*((bool*)(d.data.data))} (bool)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 156">{*((float*)(d.data.data))} (float)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 196">{*((int*)(d.data.data))} (i)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 336">{*((QChar*)(d.data.data))} (QChar)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 344">{*((QColor*)(d.data.data))} (QColor)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 372">{*((QByteArray*)(d.data.data))} (QByteArray)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 444">{*((QDate*)(d.data.data))} (QDate)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 480">{*((QTime*)(d.data.data))} (QTime)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 624">{*((QRect*)(d.data.data))} (QRect)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 660">QRectF data not available</DisplayString> <DisplayString Condition="(d.packedType&1023) == 696">{*((QSize*)(d.data.data))} (QSize)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 732">{*((QSizeF*)(d.data.data))} (QSizeF)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 768">{*((QLine*)(d.data.data))} (QLine)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 804">QLineF data not available</DisplayString> <DisplayString Condition="(d.packedType&1023) == 820">{*((uint*)(d.data.data))} (ui)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 840">{*((QPoint*)(d.data.data))} (QPoint)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 856">{*((quint64*)(d.data.data))} (ui64)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 876">{*((QPointF*)(d.data.data))} (QPointF)</DisplayString> <DisplayString Condition="(d.packedType&1023) == 892">{*((double*)(d.data.data))} (double)</DisplayString> <DisplayString> {d.packedType & 1023} </DisplayString> </Type> </AutoVisualizer>
-
@Chamile said in Qt6Natvis any1?:
Hi,
I also searched for a Qt6 natvis but still did't found one, so I tried to adapt the existing one from Qt5. Many datatypes have changed to be much more easier for debugging now and I could make working the most relvant ones like QString, QByteArray, QList (including QStringList) and all the simple types.
Thank you lots for this! I've been using it for months now but I never got to work the QList/Vector/etc to properly print each item. I'm stuck with size only data and no content.
Were you able maybe to solve it ?
Im trying to fix it now but I've got no idea what I'm doing or where to look for answers... my current lldb outut >
Evaluate '' in context of 'cc' of type 'QList<int>' Returning value with error: error: error: No value Evaluate 'd->end - d->begin' in context of 'cc' of type 'QList<int>' Evaluate failed (can't parse expression): error: error: no member named 'begin' in 'QArrayDataOps<int>' Error occurred: error: error: no member named 'begin' in 'QArrayDataOps<int>' No child provider found for 'QList<int>'
-
Now there is something:
https://download.qt.io/official_releases/vsaddin/
https://download.qt.io/official_releases/vsaddin/qt6.natvisfrom @firefly by www.c-plusplus.net/forum