VLD object being destroyed before other singletons

Oct 15, 2010 at 6:15 PM

Hi,

I am using VS2008 SP1 and Qt 4.6.2. My project is linked with VLD 2.0b.
In vld.ini, I specified "ForceIncludeModules = QtCored4.dll QtGuid4.dll QtXmld4.dll ..." so the Qt dlls are properly watched by VLD.

Unfortunately, VLD says there is a huge amount of leaks in Qt. I found out it is due to VLD being destroyed before Qt's global objects (most of them constructed using the Q_GLOBAL_STATIC helper macro).

Here are two screenshots of call stacks taken during process shutdown: one taken when the VLD object is destroyed (happens first), and another taken when Qt global data is destroyed (happens later). Only the main thread exists.

Any idea why VLD this is happening? Is there a way to have the vld object destroyed last? Is the module load order (as shown by the visual studio debugger in the output pane) likely to influence the object destruction order? If so, how to change the dll load order?

Thanks for your time and keep up the great work,
Cyril

Oct 18, 2010 at 6:18 PM

Does Qt have a sort of 'QtDestroy()' function so you can force the cleanup of Qt in your app code?

Oct 18, 2010 at 7:11 PM
Edited Oct 18, 2010 at 7:13 PM

Unfortunately not. Most of the leaks I am talking about are objects allocated on the heap using the Q_GLOBAL_STATIC macro. Here is an example of how it is used throughout Qt's cpp files:

// declares a lazy-constructed singleton of type vector<int> and accessible through the global function "vector<int> *numberz()"
Q_GLOBAL_STATIC(vector<int>, numberz)

... which unwinds to the following code: (the code may look weird since I simplified it to strip off all the thread-safety complexity)

template <typename T>
class QGlobalStaticDeleter
{
public:
    QGlobalStaticDeleter(T *t) : _t(t) {}
    inline ~QGlobalStaticDeleter() { delete _t; }
private:
    T *_t;
};

static vector<int> * this_numberz = 0;

static vector<int> * numberz()
{
    if (!this_numberz) {
        this_numberz = new vector<int>();
        static QGlobalStaticDeleter<vector<int> > cleanup(this_numberz);
    }
    return this_numberz;
}

 

Jan 19, 2011 at 3:44 AM

Hi,

I also use Qt and have managed to alleviate the problem (mostly). I added the following pragma inside the VLD source and then rebuilt the VLD lib and dll. The pragma argument "compiler" is reserved for CRT initialisation but I think it is valid to use it for VLD in this case so that its statics get created first (and therefore destroyed last). 

#pragma init_seg(compiler)

Hope this helps,

Regards,

Nick Georghiou