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 745066 - GtkFontChooserDialog creation fails when GTK is locally loaded
GtkFontChooserDialog creation fails when GTK is locally loaded
Status: RESOLVED NOTGNOME
Product: gtk+
Classification: Platform
Component: .General
3.14.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2015-02-24 05:29 UTC by Scott Talbert
Modified: 2015-08-05 21:55 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Scott Talbert 2015-02-24 05:29:32 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?
Comment 1 Matthias Clasen 2015-02-24 14:37:20 UTC
Before we go too far down this road, can you explain why you want to use gtk in this way ?
Comment 2 Emmanuele Bassi (:ebassi) 2015-02-24 14:55:17 UTC
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.
Comment 3 Scott Talbert 2015-02-24 15:08:11 UTC
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.
Comment 4 Matthias Clasen 2015-02-24 15:20:55 UTC
I have to admit that I am not too optimistic about that kind of setup having a chance of working reliably.
Comment 5 Scott Talbert 2015-02-24 15:28:19 UTC
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?
Comment 6 Emmanuele Bassi (:ebassi) 2015-02-24 15:41:53 UTC
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
>>>
Comment 7 Matthias Clasen 2015-02-24 16:46:23 UTC
(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...
Comment 8 Emmanuele Bassi (:ebassi) 2015-02-24 16:52:18 UTC
It would be good to document the requirement for using dlopen() with GTK+:

 * use RTLD_LAZY
 * never unload the shared library
 * other?
Comment 9 Scott Talbert 2015-02-24 18:20:47 UTC
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?
Comment 10 Scott Talbert 2015-02-25 01:08:20 UTC
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.
Comment 11 Matthias Clasen 2015-03-01 16:03:50 UTC
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.
Comment 12 Scott Talbert 2015-03-01 16:16:09 UTC
(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.
Comment 13 Matthias Clasen 2015-08-05 21:55:26 UTC
I don't think there is much we can do here.