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

Reply via email to