GNOME Bugzilla – Bug 140329
Workaround dlopen(NULL, 0) brokenness
Last modified: 2018-05-24 10:31:24 UTC
First, a bit of background about where the problem exposes, which may seem completely unrelated to glib. When using Evolution under NetBSD, many widgets (but not all) in the Settings dialog can't be created. This is because the initialization function for them can't be located by libglade (the library used to create them at runtime). libglade uses the global symbol table of a program, returned by g_module_open(NULL, 0), to locate those initialization functions. This works properly in almost all programs (because the functions are located in the binary itself or in libraries linked at build time), but fails in Evolution (because the functions are located in libraries dlopen'ed at run time). Quoting NetBSD's dlopen(3) manpage: If the first argument is NULL, dlopen() returns a handle on the global symbol object. This object provides access to all symbols from an ordered set of objects consisting of the original program image and any dependencies loaded during startup. Note that it says nothing about searching the symbol in dlopen'ed objects. This behavior is not correct, according to POSIX: http://www.opengroup.org/onlinepubs/007904975/functions/dlopen.html It will be fixed, some day. But for now, and for not-so-old version of NetBSD, the function is broken, meaning that evolution (and probably other programs!) won't work properly. Note that this might be broken in other systems, too. However, because of glib's abstraction of loadable modules, this broken behavior can be easily worked around from it: glib keeps track of all open modules so... when a program tries to query a symbol from the main module (opened with dlopen(NULL, 0) and pointed by in the code by the main_module variable) it can query all of them in a loop until the symbol is found, or no more modules remain. That way, it simulates the right dlopen(NULL, 0) behavior in a transparent way to applications. As the library already has a workaround for broken RTLD_GLOBAL usage, I feel this problem can also be fixed in glib, together that one.
Created attachment 26741 [details] [review] Proposed patch The attached patch adds a check to configure to detect if dlopen(NUll, 0) is broken. In that case, it modifies the g_module_symbol function to query all open modules, instead of just the main one, to look for global symbols.
Looks reasonable to me in general, just a couple of questions: - You use libintl in the configure test. Is that guaranteed to be available ? What if it is not ? - Is the order in which you search the modules the same one in which a correct dlopen() implementation would search them ? Regarding formatting: we use the convention foo (bar) rather than foo(bar).
The configure check should probably be redone using the small test library which is now built for the RTLD_GLOBAL test. Regarding the search order for the modules, POSIX seems to specify that the modules are searched in "dependency order", which might be a bit hard to redo here.
The "Fix compilation on Android with the bionic C library" Bug 689223 patch: https://git.gnome.org/browse/glib/commit/?id=bcbaf1bef01c669715860299fe8603bc21b0e137 seems to have side stepped all of this with: --- a/gmodule/gmodule-dl.c +++ b/gmodule/gmodule-dl.c @@ -113,7 +113,11 @@ _g_module_self (void) * are required on some systems. */ +#ifdef __BIONIC__ + handle = RTLD_DEFAULT; +#else handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); +#endif if (!handle) g_module_set_error (fetch_dlerror (TRUE)); #if defined(__BIONIC__) || defined (__NetBSD__) might do the trick - for that matter, any advantage in not always using RTLD_DEFAULT? Looking at evolution 2.32.3, shell/e-shell-meego.c, I see the call to module = g_module_open (NULL, 0); as filename == NULL, handle will be retrieved in _g_module_self, so the above patch should do the trick. Comments?
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/19.