Hello Qt developers,
A bit of background:
Due to a limited amount of RAM on our embedded platform and lack of multiprocess support in directFB 1.0, we are forced to load Qt libraries dynamically with dlopen / dlclose calls. Using this approach, we should be able to have Qt libraries loaded only when they are required, therefore keeping the RAM usage at a minimum when they are not needed (when other non-Qt based applications are running). We have one QtWebkit based application, implemented as a shared object with a publicly exposed API function which serve as a launch call. This application is loaded and started by our main GUI process. Here is the simplified dlopen -> launch -> dlclose sequence :
int main (int argc, char** argv)
{
void *library = dlopen("somelib.so", RTLD_NOW | RTLD_GLOBAL);
int (*launch)(int, char**) = (int (*)(int, char**))dlsym(library, "launch");
/*
* launch() is a blocking call
* argc & argv arguments are forwarded to the QApplication constructor
*/
int retVal = launch(argc, argv); // returns 0 (i.e. no errors)
retVal = dlclose(library); returns 0 (i.e. no errors)
return retVal;
}
And here is the the very simplified QtWebKit based application compiled as shared object:
class Dialog : public QDialog
{
public:
Dialog(QWidget *parent = 0) : QDialog(parent), wv(0)
{
wv = new QWebView(this);
}
virtual ~Dialog()
{
delete wv;
}
protected:
QWebView *wv;
};
QApplication *a = 0;
Dialog *w = 0;
extern "C"
{
int launch(int argc, char** argv)
{
a = new QApplication(argc, argv);
w = new Dialog;
int retVal = w->exec();
delete w;
delete a;
return retVal;
}are
}
You'll notice that instead of QApplication::exec() we're using QDialog::exec(). This is because we've found (the hard way) that multiple QApplication::exec() calls within a single process don't work. Anyways, the behavior we are experiencing with this scenario is that after dlclose() call from the main app, "cat /proc/pid/maps" shows that Qt libraries are still there. After a bit of investigation we have found that if we are not using QtWebkit and QtNetwork libraries (just QtCore and QtGui which are sufficient to display a QDialog) dlclose succeeds, i.e. those two Qt libraries are unloaded from the process memory map.
The strange thing we've encountered is that if the libQtNetwork is stated as our dynamically loaded application dependency (by "QT = gui core network" in the .pro file), a segfault occurs at dlclose(). This happens even if no instance of any QtNetwork module class is created. It is sufficient to state the QtNetwork as a dependency and display an empty QDialog. It will crash on dlclose(). Same thing happens if QtWebkit is added as a dependency.
This is reproducible 10 out of 10 times on both MIPS LE platform with the Qt 4.7.2 and on a x86 PC with the Qt 4.7.4.
Our main concern is not the segfault, but the fact that we can't unload the Qt libraries using dlclose.
Any question, advice, or feedback is highly appreciated.
Thanks,
Miroslav