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 656314 - wnck_screen_get_default() segfaults when using introspection - need to import all dependencies
wnck_screen_get_default() segfaults when using introspection - need to import...
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: introspection
unspecified
Other Linux
: Normal major
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks: 626254 698005
 
 
Reported: 2011-08-10 21:49 UTC by Joanmarie Diggs (IRC: joanie)
Modified: 2015-10-26 08:44 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
stacktrace (5.90 KB, text/plain)
2011-08-10 21:49 UTC, Joanmarie Diggs (IRC: joanie)
  Details
Add private gi._gi.Repository.get_dependencies() method to Python (3.16 KB, patch)
2014-08-31 00:25 UTC, Simon Feltman
none Details | Review
Import dependencies when importing typelibs from gi.repository (2.62 KB, patch)
2014-08-31 00:25 UTC, Simon Feltman
none Details | Review
Import dependencies when importing typelibs from gi.repository (6.68 KB, patch)
2015-10-04 08:18 UTC, Christoph Reiter (lazka)
committed Details | Review

Description Joanmarie Diggs (IRC: joanie) 2011-08-10 21:49:24 UTC
Created attachment 193603 [details]
stacktrace

$ python
>>> import wnck
>>> wnck.screen_get_default()
<wnck.Screen object at 0x27d8460 (WnckScreen at 0x281c010)>

~~~~~~~~~~~

$ python
>>> from gi.repository import Wnck
>>> Wnck.Screen.get_default()

(process:20645): Gdk-CRITICAL **: gdk_x11_display_get_xdisplay: assertion `GDK_IS_DISPLAY (display)' failed
Segmentation fault


I can reproduce this reliably on two Fedora 16 (branched) boxes. Apologies if this is a downstream/unstable-release thing....
Comment 1 Johan (not receiving bugmail) Dahlin 2011-08-11 11:37:46 UTC
This is probably a missing/incorrect transfer annotation for wnck_screen_get_default().
Comment 2 Joanmarie Diggs (IRC: joanie) 2011-08-11 16:56:16 UTC
So after some help in #python, the conclusion seems to be that the bug is a big ol' case of user (reporter) fail:

< tomeu> Internally, libwnck uses GDK. This means that before any call to libwnck API, GDK needs to be initialized. This can be achieved with gdk_init(), or indirectly via gtk_init().
< tomeu> joanie: I think just importing Gdk would do it
< joanie> k I'll try
< joanie> oh man
< joanie> lol
< joanie> that works
< tomeu> \o/

Sorry! (And thanks guys!!)
Comment 3 Joanmarie Diggs (IRC: joanie) 2011-08-11 18:27:06 UTC
< jdahlin> joanie: it's a bug, Gdk.init() shouldn't be needed, perhaps the Gdk override should call it automatically
< joanie> jdahlin: would you like me to reopen the bug?
< jdahlin> joanie: sure, I think it represents a valid problem

Reopening and moving to pygobject.
Comment 4 johnp 2011-09-15 20:03:12 UTC
So Gdk does already do the init.  The problem is you need to import Gdk for the overrides to load.  Perhaps we should iterate through all the gir's dependency's and import those modules.
Comment 5 Martin Pitt 2012-04-17 10:25:05 UTC
Indeed, this works:

>>> from gi.repository import Gdk, Wnck
>>> Wnck.Screen.get_default()
<Screen object at 0x7f6a91f9ce60 (WnckScreen at 0x15df830)>

It's not related to the overrides (the exact same problem/fix also works without Gdk overrides), we just need to take care of importing dependencies.
Comment 6 Martin Pitt 2013-02-27 15:11:25 UTC
*** Bug 673396 has been marked as a duplicate of this bug. ***
Comment 7 Simon Feltman 2013-04-15 12:59:27 UTC
*** Bug 698005 has been marked as a duplicate of this bug. ***
Comment 8 Tobias Mueller 2014-05-06 03:21:14 UTC
As it's mentioned in bug 698005,

from gi.repository import Gtk, GdkX11

might help.
Comment 9 Simon Feltman 2014-08-31 00:25:22 UTC
Created attachment 284916 [details] [review]
Add private gi._gi.Repository.get_dependencies() method to Python

Add static wrapper for g_irepository_get_dependencies() for usage with
auto-loading dependent typelibs.
Comment 10 Simon Feltman 2014-08-31 00:25:26 UTC
Created attachment 284917 [details] [review]
Import dependencies when importing typelibs from gi.repository

Recursively import a modules dependencies when importing from gi.repsository.
Comment 11 Simon Feltman 2014-08-31 00:34:19 UTC
Slightly concerned over performance implications of the patches. We need to test load times before and after and either commit this or mark the bug as won't fix depending on the outcome after the 3.14 release.
Comment 12 Christoph Reiter (lazka) 2015-07-03 12:39:15 UTC
Not sure why, but importing

"from gi.repository import GLib, GObject, Atk, GdkPixbuf, Gio, Pango, cairo, Gdk, xlib, Gtk"

is 30% faster here than just

"from gi.repository import Gtk"

the important things seems to be that Gdk is imported before Gtk. Any idea why that could be?
Comment 13 Christoph Reiter (lazka) 2015-10-04 08:18:44 UTC
Created attachment 312621 [details] [review]
Import dependencies when importing typelibs from gi.repository

Recursively import a modules dependencies when importing from
gi.repository.

This fixes the case where a library depends on initialization
code of dependency overrides. For example libwnck expects
gdk_init to be called before using its API and gdk_init
gets called in the Gdk overrrides.
Comment 14 Christoph Reiter (lazka) 2015-10-04 08:32:10 UTC
(In reply to Martin Pitt from comment #5)
> Indeed, this works:
> 
> >>> from gi.repository import Gdk, Wnck
> >>> Wnck.Screen.get_default()
> <Screen object at 0x7f6a91f9ce60 (WnckScreen at 0x15df830)>
> 
> It's not related to the overrides (the exact same problem/fix also works
> without Gdk overrides), we just need to take care of importing dependencies.

I can't reproduce this. libwnck segfaults because gdk_display_get_default returns NULL which is fixed by calling gdk_init() in the overrides.

(In reply to Christoph Reiter (lazka) from comment #12)
> Not sure why, but importing
> 
> "from gi.repository import GLib, GObject, Atk, GdkPixbuf, Gio, Pango, cairo,
> Gdk, xlib, Gtk"
> 
> is 30% faster here than just
> 
> "from gi.repository import Gtk"
> 
> the important things seems to be that Gdk is imported before Gtk. Any idea
> why that could be?

Turns out that calling gdk_init()+gtk_init() is 40ms faster than just calling gtk_init() alone. Including a construction of a GtkWidget the time spend is the same again, so I suspect some lazy loading differences. Needs investigating (faster import would be nice, even if the work just gets shifted elsewhere)

------

Regarding the above updated patch:

* It uses the new get_immediate_dependencies() as get_dependencies behavior was changed in recent libgirepository.
* It uses is_registered() as a fast path to check if a namespace is available on import which saves 5ms when importing lots of dependencies.

Performance impact:

* "from gi.repository import Gdk, Gtk" ~4ms slower
* "from gi.repository import Gdk, Gtk, ClutterGdk" ~5ms slower

ClutterGdk has ~20 dependencies, so all in all it doesn't seem too bad.
Comment 15 Christoph Reiter (lazka) 2015-10-10 22:20:15 UTC
(In reply to Christoph Reiter (lazka) from comment #14)
> Turns out that calling gdk_init()+gtk_init() is 40ms faster than just
> calling gtk_init() alone. Including a construction of a GtkWidget the time
> spend is the same again, so I suspect some lazy loading differences. Needs
> investigating (faster import would be nice, even if the work just gets
> shifted elsewhere)

This turned out to be bug 756147 which is now fixed in gtk+ trunk.
Comment 16 Simon Feltman 2015-10-25 19:29:03 UTC
Review of attachment 312621 [details] [review]:

LGTM, thanks.