[Development] Issues with dynamically loading of Qt libraries (libQtNetwork and libQtWebKit)

Miroslav Ristic risticmiroslav at gmail.com
Wed Apr 4 00:12:41 CEST 2012


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);
    wv->load(QUrl("http://google.com"));
  }
  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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20120403/c23b3a1c/attachment.html>


More information about the Development mailing list