After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 705535 - Segmentation fault when dynamically load, unload and reload gobject
Segmentation fault when dynamically load, unload and reload gobject
Status: RESOLVED NOTABUG
Product: glib
Classification: Platform
Component: gobject
2.36.x
Other Linux
: Normal minor
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2013-08-05 21:49 UTC by Cédric D.
Modified: 2014-06-01 15:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Program to reproduce the bug by loading and unload libgobject (2.09 KB, text/plain)
2013-08-05 21:49 UTC, Cédric D.
Details

Description Cédric D. 2013-08-05 21:49:43 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.
Comment 1 Colin Walters 2013-08-05 22:40:04 UTC
Just have VLC always link with gobject?

Or failing that, do not unload libgobject.
Comment 2 Cédric D. 2013-08-06 07:39:23 UTC
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:
  • #0 ??
    from /lib64/libc.so.6
  • #1 g_str_equal
    at ghash.c line 1706
  • #2 g_hash_table_lookup_node
    at ghash.c line 386
  • #3 g_hash_table_lookup
    at ghash.c line 1076
  • #4 quark_from_string
    at gquark.c line 173
  • #5 g_quark_from_static_string
    at gquark.c line 239
  • #6 gobject_init_ctor
    at gtype.c line 4365
  • #7 ??
    from /lib64/ld-linux-x86-64.so.2
  • #8 ??
    from /lib64/ld-linux-x86-64.so.2
  • #9 ??
    from /lib64/ld-linux-x86-64.so.2
  • #10 ??
    from /lib64/ld-linux-x86-64.so.2
  • #11 ??
    from /lib64/ld-linux-x86-64.so.2
  • #12 ??
    from /lib64/libdl.so.2
  • #13 ??
    from /lib64/ld-linux-x86-64.so.2
  • #14 ??
    from /lib64/libdl.so.2
  • #15 dlopen
    from /lib64/libdl.so.2
  • #16 module_Load
    at posix/plugin.c line 62

Comment 3 Colin Walters 2013-08-06 09:12:52 UTC
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...)
Comment 4 Emmanuele Bassi (:ebassi) 2013-08-06 09:13:53 UTC
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.
Comment 5 Cédric D. 2013-08-06 11:44:03 UTC
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 ;)
Comment 6 Colin Walters 2013-08-06 13:06:49 UTC
Ok, thanks!
Comment 7 Tijl Coosemans 2014-06-01 15:28:08 UTC
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.
Comment 8 Alexandre Rostovtsev 2014-06-01 15:41:28 UTC
(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 :)