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

56 views
Skip to first unread message

Miroslav Ristic

unread,
Apr 3, 2012, 6:12:41 PM4/3/12
to devel...@qt-project.org
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

Thiago Macieira

unread,
Apr 3, 2012, 7:20:08 PM4/3/12
to devel...@qt-project.org
On terça-feira, 3 de abril de 2012 15.12.41, Miroslav Ristic wrote:
> 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.

Unloading libraries is always a recipe for disaster. You can't unload if there
are threads running or other things still allocated. That's probably the
reason why you get that segfault when you try to unload it.

Now, none of the libraries has -z nodelete, so the only thing that would keep
it from unloading are plugins. And besides the designer/libqwebview.so plugin,
I can't see any other plugin linked to QtWebKit.

Anyway, my suggestion is: don't try. Just forget about unloading the libraries
from memory.

--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden

signature.asc
Reply all
Reply to author
Forward
0 new messages