PDA

View Full Version : Qt crashing during threaded QQL init + lib load (4.8.4)



ZHawk
29th May 2013, 10:07
Hello,
I have an issue when loading libs and initializing databases in threads.
Qt 4.7.4 seems to be fine but Qt 4.8.4 is giving me random crashes.
My heap seems to get corrupted somehow but there are no operations that are manipulating any memory.
Basically this program is adding a database, checking if a database driver is available and loading a library (not using it). All of them are done in different threads.

As this is a random crash, it takes up to 10 restarts in most cases untill you can encounter a crash.

I have created a minimal example (Visual Studio 2010):
9079

I know that the thread usage is bad style (I should use QThread as an interface) but I need to know why this is crashing and what I am doing wrong.

Below is the code in just one file (in case you do not want to download):

#include <QApplication>
#include <QMainWindow>
#include <QObject>
#include <QString>
#include <QThread>
#include <QLibrary>
#include <QSqlDatabase>
#include <QDebug>
#include <QMutex>
class Worker;

class MyClass : public QMainWindow
{
public:
MyClass(QWidget *parent = 0, Qt::WFlags flags = 0);
~MyClass(){};
};

class CheckThread : public QThread
{
private:
Worker *worker;
public:
CheckThread( Worker *worker )
{
this->worker = worker;
};
void run( );
};

class DBThread : public QThread
{
public:
DBThread( ){};
void run( );
};

class Worker
{
public:
Worker( ){ };
~Worker( ){ };
static void loadDriver( );
void loadLib( QString libName );
void checkDB( );
void checkDB_thread( );
private:
CheckThread *checkThread;
QLibrary *m_lib;
};

QMutex conMutex;
DBThread *dbThread;

void DBThread::run( )
{
QMutexLocker locker(&conMutex);
QSqlDatabase::addDatabase("QSQLITE", "sqLiteConn");
}

void CheckThread::run( )
{
this->msleep(100);
worker->checkDB_thread();
}

void Worker::loadDriver( )
{
dbThread = new DBThread();
dbThread->start();
}

void Worker::loadLib( QString libName )
{
m_lib = new QLibrary(libName);
m_lib->load();
}

void Worker::checkDB( )
{
checkThread = new CheckThread(this);
checkThread->start();
}

void Worker::checkDB_thread( )
{
QMutexLocker locker(&conMutex);
QSqlDatabase::isDriverAvailable("QODBC");
}

MyClass::MyClass(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
Worker::loadDriver(); // loading is done in thread 1 (global thread)

Worker *driverCheckWorker = new Worker();
driverCheckWorker->checkDB(); // check if driver exists in thread 2 (private thread)

Worker *dllWorker = new Worker();
dllWorker->loadLib("../plugins/sqldrivers/qsqlite4.dll"); // lib is being loaded in main thread
}

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyClass w;
// crash will occur before calling w.show()
w.show();
return a.exec();
}

Thank you in advice.