Re: Proposed Fix for GTK3 Crashes - dlopen flags

Scott Talbert <[email protected]>
Newsgroups gmane.comp.python.wxpython.devel
Message-ID <[email protected]>
On Tue, 24 Feb 2015, Scott Talbert wrote:

> I've been working on investigating a couple of crashes that occur with 
> wxPython 3.0.2.0 with a GTK+3 backend:
> http://trac.wxwidgets.org/ticket/16820
>
> There is a similar crash that occurs when using a wx.Printer.
>
> Anyway, I've spent considerable time investigating these and found that the 
> crash is because GTK performs some dlsym() calls to lookup symbol names and 
> fails in going so because its symbols were loaded in the local namespace, not 
> the global namespace (ie, RTLD_LOCAL vs RTLD_GLOBAL). I've discussed this 
> with the GTK devs and basically, GTK expects its symbols to be loaded 
> globally.
>
> Thus, I have a solution that I would like to propose for discussion:
>
> diff -up wxPython/src/__init__.py.dlopenflags wxPython/src/__init__.py
> --- wxPython/src/__init__.py.dlopenflags	2013-02-27 15:14:01.000000000 
> -0500
> +++ wxPython/src/__init__.py	2015-02-24 20:43:44.143492336 -0500
> @@ -42,7 +42,11 @@ __all__ = [
>     ]
>
> # Load the package namespace with the core classes and such
> +import dl, sys
> +flags = sys.getdlopenflags()
> +sys.setdlopenflags(flags|dl.RTLD_GLOBAL)
> from wx._core import *
> +sys.setdlopenflags(flags)
> del wx
>
> if 'wxMSW' in PlatformInfo:
>
> ===
>
> Basically, this would change the dlopen flags before importing the core 
> module to RTLD_GLOBAL and then change them back afterwards.  That way, the 
> core module and its dependencies (to include GTK) are loaded into the global 
> namespace.
>
> Comments on this proposal?
>
> It needs more work but I wanted to get feedback before finalizing a patch. 
> (ie, it probably only needs to be done on when we're using a GTK+3 backend, 
> needs to check whether the dl module is available, etc.)

Okay, here's an updated version of the patch.  Unfortunately, it isn't 
possible to check the backend (and only change the dlopen flags if on 
GTK+3) because the backend isn't known until _core.so is imported.  After 
that point, it's too late.

It's possible that we could somehow have SWIG put this into the generated 
_core.py only for GTK+3, but I'm not sure how to do that.

Comments?

Thanks,
Scott
dlopenflags_v2.patch (text/x-diff, 1.2 KB)
diff -up wxPython-src-3.0.2.0/wxPython/src/__init__.py.dlopenflags wxPython-src-3.0.2.0/wxPython/src/__init__.py
--- wxPython-src-3.0.2.0/wxPython/src/__init__.py.dlopenflags	2013-02-27 15:14:01.000000000 -0500
+++ wxPython-src-3.0.2.0/wxPython/src/__init__.py	2015-02-28 20:14:07.653903689 -0500
@@ -41,10 +41,31 @@ __all__ = [
     'stc',
     ]
 
+# GTK3 expects all of its library symbols to be loaded into the global
+# namespace.  Temporarily change the dlopen flags to include RTLD_GLOBAL before
+# importing the core module so it will pull its libraries into the global NS. 
+import sys
+_RTLD_GLOBAL = 0
+try:
+    from dl import RTLD_GLOBAL as _RTLD_GLOBAL
+except ImportError:
+    try:
+        from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL
+    except ImportError:
+        pass
+
+if _RTLD_GLOBAL != 0:
+    _dlopenflags = sys.getdlopenflags()
+    sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL)
+
 # Load the package namespace with the core classes and such
 from wx._core import *
 del wx
 
+# If we changed the dlopen flags earlier, change them back.
+if _RTLD_GLOBAL != 0:
+    sys.setdlopenflags(_dlopenflags)
+
 if 'wxMSW' in PlatformInfo:
     __all__ += ['activex']
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.