[Development] qt_add/removeObject hooks

Poenitz Andre Andre.Poenitz at digia.com
Tue Apr 8 16:39:18 CEST 2014


volker.krause at kdab.com:
> > > So unless there's some compiler magic I missed I think this needs a
> > > different  approach to be reliable and cross-platform, such as callbacks.
> > > Would this be acceptable? If so, would a minimal approach similar to
> > > qt_register_signal_spy_callbacks() or rather something using
> > > QInternal::registerCallback() be preferred?
> >
> > We should probably move those functions to a separate .cpp, so the optimiser
> > doesn't kick in. We don't build with LTCG enabled.
> 
> I tried to avoid tricks that more or less worked by accident, in order to have
> something that would survive the next compiler update. With explicit compiler
> flags to disable optimization for the separate files this might work though.

I think that creating some setup relying on the optimizer to work (or even
not work) in a specific way is quite fragile.

> > But feel free to make the best API that works for GammaRay and for Squish.
> > You're the only users of such an API. We'll abide by the solutions you come
> > up with.
> 
> API-wise we are quite flexible (can't get any more dirty than what we do now
> ;) ), I was mainly asking due to this being on a performance-relevant path.
> The QInternal callback system is obviously more flexible (and thus would be my
> preferred choice), but also slightly more expensive at runtime. The signal spy
> approach would be slightly more light-weight, at the cost of thread-safety.
> So, if from the performance point of view there are no objections to the
> QInternal callback approach, I'll make sure the Squish team is happy with that
> too, and propose a patch accordingly.
> 
> Should this include the removal of the old add/removeObject hooks or are they
> considered public API (they are exported)?

Isn't all that is needed just one indirection through a function pointer stored in 
some global variable, i.e roughly something like


// hookstuff.h
#include <Qt>
extern quintptr qHookStuff[];

// hookstuff.cpp
#include <stdio.h>

void qFooHook() { printf("fooo....\n"); }

// Only add to the end, and bump version if you do.
quintptr qHookStuff[5] = {
    1, // version 
    sizeof(qHookStuff) / sizeof(qHookStuff[0]), // length
    QT_VERSION,
    (quintptr)&qFooHook,
    42,
};

// "User"

#include <Qt>

void myFoo() { printf("bar....\n"); }

int main()
{
    const int fooIndex = 3;

    Q_ASSERT(qHookStuff[0] > 0);  // minimum version of the extra data we want
    Q_ASSERT(qHookStuff[1] > fooIndex); // half-baked sanity check there's a suitable entry
    Q_ASSERT(qHookStuff[2] > 0x30308); // minimum Qt version we want to operate on
    //...

    ((void(*)())qHookStuff[fooIndex])(); // default implementation

    debugStuff[fooIndex] = (quintptr)&myFoo; // overrider it...
    ((void(*)())debugStuff[fooIndex])();  // custom now.
}

Something like that (specifically something that does not need a function 
call to extract data like qVersion() does) would be very helpful for "normal"
debugging, too.

Add/removeObject would just be two slots in the array and can be "replaced"
at runtime, as often as needed. (or keep default as '0' and have the corelib
code check for != 0 before calling the hook)

Andre'


More information about the Development mailing list