GNOME Bugzilla – Bug 745066
GtkFontChooserDialog creation fails when GTK is locally loaded
Last modified: 2015-08-05 21:55:26 UTC
When GTK+ is loaded locally, ie, with dlopen(xxx, RTLD_LOCAL), GtkFontChooserDialog creation fails with: Gtk-WARNING **: Unknown type PangoFontFace specified in treemodel model Gtk-WARNING **: gtkliststore.c:516: Invalid type (null) This is because the dlsym() lookup for pango_font_face_get_type fails. This is similar to the problem report in bug #710096 and 745065. It seems that perhaps GtkFontChooserDialog should have a g_type_ensure for PangoFontFace?
Before we go too far down this road, can you explain why you want to use gtk in this way ?
I assume is this: https://mail.gnome.org/archives/gtk-list/2015-February/msg00080.html > What I neglected to mention in the first place is that this failure is > occurring when running as a Python application (wxPython to be specific). > When I run the same code as a C++ application (wxWidgets), the failure > does not occur. Presumably this failure is occurring because the python > binary itself is not linked with the GTK+ library.
That's right. This is a case of using GTK from a Python extension module (wxPython). Python seems to dlopen() its extension modules with RTLD_LOCAL, and thus when GTK (linked to the Python extension module) later does a dlsym() it doesn't see the symbols it is looking for.
I have to admit that I am not too optimistic about that kind of setup having a chance of working reliably.
Why not? And do you have any suggestions for alternative solutions? I suppose we could try to dlopen() the extension module with RTLD_GLOBAL, but is that safe?
We consistently use RTLD_LAZY inside introspection, and thus in the Python bindings, and trying to load a FontChooserDialog works, at least on Linux: Python 2.7.8 (default, Nov 10 2014, 08:19:18) [GCC 4.9.2 20141101 (Red Hat 4.9.2-1)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from gi.repository import Gtk >>> c = Gtk.FontChooserDialog() >>> c.show() Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged. >>> c.run() -6 >>>
(In reply to Scott Talbert from comment #5) > Why not? And do you have any suggestions for alternative solutions? I > suppose we could try to dlopen() the extension module with RTLD_GLOBAL, but > is that safe? I'm not too optimistic, because this is not how gtk+ is normally used. It is going break over and over again, forcing us into whack-a-mole fixes adding more and more random g_ensure_type calls...
It would be good to document the requirement for using dlopen() with GTK+: * use RTLD_LAZY * never unload the shared library * other?
Is RTLD_LAZY (vs RTLD_NOW) really coming into play here? I would think that even if the symbols are loaded lazily, if they are not loaded into the global namespace, then GTK still won't be able to see them?
I see now what GI is doing. In gitypelib.c: module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY); G_MODULE_BIND_LAZY ends up translating to (in gmodule-dl.c): dlopen (file_name, RTLD_GLOBAL | RTLD_LAZY); So, GI is loading global and lazy.
As another workaround, you can try calling gtk_test_register_all_types after gtk_init. You'll still have problems with types from other libraries, I'm afraid.
(In reply to Matthias Clasen from comment #11) > As another workaround, you can try calling gtk_test_register_all_types after > gtk_init. You'll still have problems with types from other libraries, I'm > afraid. That won't help in this case, unfortunately, because PangoFontFace won't get loaded. It won't help with GtkPrinterOperation either because GtkPrinterOptionWidget doesn't get included in gtktypefuncs.c.
I don't think there is much we can do here.