On Sun, Oct 17, 2010 at 06:09:37AM +0200, tbp wrote:
> Hello,
>
> after going through the Peek & Poke serie, the documentation and
> gdbmacros.py, yesterday, for a few hours, i tried to have the debugger
> display sensible information about, say, __m128i; the only appreciable
> result being an elevated blood pressure.
>
> Now that i can express myself without expletives every other word, a
> few bullet points:
> . user made dumpers are simply not working in 2.1.0 beta1 (2.0.92,
> x86-64 linux).
They are, but "simply not working" is "simply no good bugreport".
> . but they do back in, ie, 2.0.1 (revision 97d831e3de).
> . there's no way tell what's going on, going through pages after
> pages of cryptic log is an exercise in futility.
Post it here or on pastebin and ask here or on IRC for help.
> . even armed with a possibly working custom dumper, "native" types
> are ignored; can't overload them.
You can modify the framework itself in dumper.py and do arbitrary things
to arbitrary types.
> . and if you wrap such type (and defeat the purpose), pick it out,
> then, you're left wondering how one's supposed to manipulate them;
> implementations for other types provide no clue.
?
> To sum it up, the default display for packed scalars is severely
> lacking: __m128 and __m128i are in fact aliasing a whole family of
> types and while gdb knows about, you can't cast to, say, __v16qi on
> the fly in qt creator's debugger. A custom dumper is required, but as
> far as know, it's not even possible.
>
> Help.
Alright. Let's have a look and create a transcript of the "session".
Start with some random example code found with google:
#include <xmmintrin.h>
#include <stddef.h>
int main()
{
float a[4];
float b[4];
for(size_t i = 0; i < 4; i++) {
a[i] = 2 * i;
b[i] = 2 * i;
}
__m128 sseA, sseB;
sseA = _mm_loadu_ps(a);
sseB = _mm_loadu_ps(b);
return 0;
}
Put a breakpoint on 'return', F5. Right. No nice display for sseA
and sseB. Interesting enough, gdb seems to be a little confused itself:
ptype sseA
type = float [0]
p sseA
$37 = 0xbffff8a0
Note the "[0]". Huh?
However, we have an address and a type. That should be good enough.
Start with Locals and Watchers, context menu, first entry "Watch
expression *(__m128*)0xbffff8a0" or such. This creates a new watcher,
replace the "*(__m128*)" by "{float[4]}" and we see four float values.
So there is a way to do it "somehow", let's try to do it properly:
Start with a dummy dumper:
def qdump____m128(d, item):
d.putValue("xx")
d.putNumChild(0)
Looks a bit funny due to the four underscores, two from the fixed
qdump__ prefix and two from '__m128', but the user won't see that.
Check it is properly found next time the dumpers are listed on startup:
{type=\"__m128\",formats=\"\"}
Good. But... looking at the Locals it's not used. Why? Maybe gdb _does_
know something about it is special.
python print gdb.parse_and_eval("sseA").type.code
yields 23. A typedef. And stripping it yields "float[0]". Not good.
The dumper framework works on the "base type", and "float[0]" is not
a proper type. The only way to fix it is to catch it on the framework
level before stripping the typedefs:
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -1477,12 +1477,16 @@ class Dumper:
if self.useFancy \
and ((format is None) or (format >= 1)) \
- and ((nsStrippedType in qqDumpers) or isQObjectDerived):
+ and ((nsStrippedType in qqDumpers) \
+ or isQObjectDerived
+ or str(type) in qqDumpers):
#warn("IS DUMPABLE: %s " % type)
#self.putAddress(value.address)
self.putType(realtype)
if nsStrippedType in qqDumpers:
qqDumpers[nsStrippedType](self, item)
+ elif str(type) in qqDumpers:
+ qqDumpers[str(type)](self, item)
elif isQObjectDerived:
# value has references stripped off item.value.
item1 = Item(value, item.iname)
No we have the __m128 variables displayed as "xx", so the dumper is
used. Time to replace it with a real implementation:
def qdump____m128(d, item):
d.putValue(" ")
d.putNumChild(4)
if d.isExpanded(item):
innerType = lookupType("float")
p = item.value.address.cast(innerType.pointer())
with Children(d, 4, innerType):
d.putItem(Item(p.dereference(), item.iname)); p += 1
d.putItem(Item(p.dereference(), item.iname)); p += 1
d.putItem(Item(p.dereference(), item.iname)); p += 1
d.putItem(Item(p.dereference(), item.iname)); p += 1
Hard coding the display to "float" might not make much sense, so make
it configurable for the user:
def qform____m128():
return "As floats,As doubles"
def qdump____m128(d, item):
d.putValue(" ")
d.putNumChild(1)
if d.isExpanded(item):
format = d.itemFormat(item)
if format == 2: # As Double
innerType = lookupType("double")
count = 2
else: # Default, As float
innerType = lookupType("float")
count = 4
p = item.value.address.cast(innerType.pointer())
with Children(d, count, innerType):
for i in xrange(count):
d.putItem(Item(p.dereference(), item.iname))
p += 1
Time for a cookie ;-)
Andre'
_______________________________________________
Qt-creator mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt-creator