GNOME Bugzilla – Bug 705535
Segmentation fault when dynamically load, unload and reload gobject
Last modified: 2014-06-01 15:41:28 UTC
Created attachment 250904 [details] Program to reproduce the bug by loading and unload libgobject If an application is linked with libglib-2.0.so and dynamically loads libgobject-2.0.so, unloads it then reloads it, a segmentation fault can occur in the constructor gobject_init_ctor() (file gobject/gtype.c, added in 2.36) due to static strings used as key for quarks. I attach a test program to reproduce the problem. I tested it on Gentoo x86_64 and on Fedora 19 x86_64 with glib 2.36.3. It should be compiled using: gcc -g -Wall `pkg-config --cflags --libs glib-2.0` -ldl test_gobject.c The problem is that quarks are stored in the libglib-2.0.so and are not destroyed when the libgobject-2.0.so is unloaded. As all keys are created using g_quark_from_static_string and g_intern_static_string, if the libgobject-2.0.so is reloaded at another address, all these string pointers become dangling and accessing the quarks may cause a segmentation fault. This behavior occurs in applications with plugins (e.g. VLC). If the main application is linked with libglib-2.0.so only (to have it always loaded) and some plugins use both libglib-2.0.so and libgobject-2.0.so, unloading then reloading these plugins leads to a segmentation fault. The "problem" was probably present before version 2.36 but it was shown only if g_type_init() was called; with the new constructor mechanism, loading the library is enough to create/access the quarks. I tried to replace g_quark_from_static_string and g_intern_static_string respectively by g_quark_from_string and g_intern_string in gobject and the problem was gone, but I think this can lead to memory leaks or another problems (I'm not a gobject/quark expert). I hope my explanations are clear enough.
Just have VLC always link with gobject? Or failing that, do not unload libgobject.
Unfortunately it is not as simple. The GUI is in Qt4 and this brings glib.so alone (libQtCore.so is linked with it); various plugins (libnotify, svg) are linked with gobject.so and they may be unloaded. I will try to find a way to keep gobject loaded. Thanks for your attention. For information, I put here part of the debug stack which shows the problem:
+ Trace 232349
What you could do is check, after loading a plugin, whether you can find the symbol "g_object_get_type", or really any of them. If so, then dlopen("libgobject-2.0.so.0"), and hold that reference permanently. (Note: you may have further problems with unloading these plugins since GObject wants plugins to use GTypeModule...)
we haven't supported unloading libgobject for a *long* while. the type system itself does not support reloading its data, and code assumes that types will survive for the entire duration of the process life time. this does not mean that unloading libgobject is never going to be implemented, but it may very well require API/ABI breakage.
Thank you for the details and suggestions. As unloading libgobject is not supported, I added -z nodelete to the LDFLAGS of my libgobject. This way all problems are gone and I don't have to make ugly hacks to keep libgobject loaded. I think you can close this bug report (I don't know if I should do it myself). And don't worry, I won't report bugs with this modified libgobject ;)
Ok, thanks!
Can you please reopen this until you add the "nodelete" flag to the proper makefiles. If you cannot safely dlclose a library it *must* be linked with -Wl,-z,nodelete. This seems to be the case for libglib, libgio and libgobject. They all call g_internal_static_string and g_quark_from_static_string.
(In reply to comment #7) This was already fixed in git for libgobject, see bug #707298; just wait for glib-2.40.1 to be released if your distro hasn't applied the patch :)