GNOME Bugzilla – Bug 153848
GTK_PATH problems on bi-arch platforms
Last modified: 2018-05-02 14:03:51 UTC
If I want to use variable GTK_PATH, I have to explicitly list platform dependent directories, e. g.: export GTK_PATH="/usr/local/lib64/gtk-2.0:/opt/gnome/lib64/gtk-2.0:/usr/lib64/gtk-2.0" Additionally, gtk fails after locating engine for different platform. There exist no setting of GTK_PATH, which allows to use 32-bit and 64-bit binaries on single machine. Either one ore second binaries use default skin. Note that with GTK_PATH unset, all works OK. Possible solutions: - GTK_PATH will contain some style of prefix+platform->gtkdir mapping (e. g. $libdir/gtk-2.0/modules/i686/). - Ignore modules with incorrect architecture. - Make GTK_PATH platform-dependent (e. g. GTK_PATH_x86_64). Related bug 129540.
Looking at glibc sources, it has a code, that interprets $LIB, $PLATFORM, and $ORIGIN in library paths. Maybe we can copy it (or create it as a glib function).
if you pass $LIB through to dlopen it should just work, as ld.so will interpret it, no ?
Maybe, but gtk part does not work, as strace log shows: access("/usr/$LIB/gtk-2.0/2.10.0/modules/libgnomebreakpad.so", F_OK) = -1 ENOENT (No such file or directory)
This still a problem today btw. eg https://bugzilla.xfce.org/show_bug.cgi?id=7483#c2 It would be better if gtk ignored loading modules with the wrong arch.
Looking deeper into the code: dlopen() expands $LIB correctly. g_module_open("/usr/$LIB/gtk-3.0/3.0.0/immodules/im-cedilla.so", G_MODULE_BIND_LAZY) does strange things but it finally does what is expected: stat("/usr/$LIB/gtk-3.0/3.0.0/immodules/im-cedilla.so", 0x7fff7f574990) = -1 ENOENT (No such file or directory) stat("/usr/$LIB/gtk-3.0/3.0.0/immodules/im-cedilla.so.so", 0x7fff7f574990) = -1 ENOENT (No such file or directory) stat("/usr/$LIB/gtk-3.0/3.0.0/immodules/im-cedilla.so.la", 0x7fff7f574990) = -1 ENOENT (No such file or directory) open("/usr/lib64/gtk-3.0/3.0.0/immodules/im-cedilla.so", O_RDONLY) = 3 But stuff using _gtk_find_module() seems to never attempt to open the file (comment 3).
I have two ideas to fix: 1) Enhance GLib gmodule API: Create a function that represents counterpart of g_file_test() for loadable modules: g_module_test() or g_module_exists(). This function will use dlopen(foo, RTLD_NOLOAD) instead of stat() in g_file_open(). Then go through all module related code and replace all occurrences of g_file_test() by g_module_test(). 2) Do not use g_file_test() at all anywhere in module context. I just went through all users of _gtk_find_module(): gtkmodules.c find_module(): Easy to fix to load without check. gtkprintbackend.c _gtk_print_backend_create(): Hard to fix to not check for file first. It creates a print backend object and loads module with a known path on demand. gtkthemingengine.c gtk_theming_module_load(): Easy to fix to load without check. gtkrc.c: gtk_rc_find_module_in_path(): Impossible to fix. Public API. But, hopefully, it is deprecated. The implementation of g_module_test() seems to be easier way: glibc systems: Use dlopen(foo, RTLD_NOLOAD) all other systems: Use stat() or call g_file_test() Regarding comment 1: It would be nice to implement some sort of string replace in the GTK_PATH string anyway. It would allow to install modules for several concurrent GTK+ versions in parallel to custom paths. The GTK_PATH can then look: GTK_PATH=/opt/vendor/$LIB/$GTK_BRANCH $GTK_BRANCH would be expanded in gtk+ before passing it to GLib, $LIB would be expanded in (and can be used only) glibc.
OOPS. 1) is not possible - according the documentation, RTLD_NOLOAD does not load and does not attempt to load the module. It returns value on already loaded modules. Only 2) can be implemented.
Well, things are even more complicated. There are even more problematic places. For example gtk/queryimmodules.c needs to list all directories in GTK_PATH. If somebody uses "$LIB" in GTK_PATH, then it is impossible - there is not glibc function that can expand "$LIB" just to list files in the directory. _dl_dst_substitute() in glibc/elf/dl-load.c is a private function. There is no public interface to get expanded string or directory listing.
Trying enhancement request for glibc that could make implementation easy: http://sourceware.org/bugzilla/show_bug.cgi?id=13623
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.
The problem is still valid and bi-arch distros like openSUSE still has to use ugly work-around patches (use GTK_PATH64 instead of GTK_PATH for 64-bit platforms). https://build.opensuse.org/package/view_file/openSUSE:Factory/gtk3/gtk3-GTK_PATH64.patch?expand=1 Another work-around is described in the comment 4. The blocking glibc bug for the nice fix is still not resolved.
-- 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/gtk/issues/237.