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 140329 - Workaround dlopen(NULL, 0) brokenness
Workaround dlopen(NULL, 0) brokenness
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: gmodule
2.4.x
Other other
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on: 139567
Blocks:
 
 
Reported: 2004-04-17 10:24 UTC by Julio Merino
Modified: 2018-05-24 10:31 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Proposed patch (4.28 KB, patch)
2004-04-17 10:26 UTC, Julio Merino
needs-work Details | Review

Description Julio Merino 2004-04-17 10:24:45 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.
Comment 1 Julio Merino 2004-04-17 10:26:20 UTC
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.
Comment 2 Matthias Clasen 2004-04-23 13:41:18 UTC
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).
Comment 3 Matthias Clasen 2004-07-04 06:12:11 UTC
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.
Comment 4 Patrick Welche 2016-03-11 17:49:48 UTC
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?
Comment 5 GNOME Infrastructure Team 2018-05-24 10:31:24 UTC
-- 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.