This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: exceptions not caught from shared libraries loaded with dlopen


On Sat, 2007-10-20 at 12:41 +0200, tahoma@gmx.de wrote:
> > > > Adding RTLD_GLOBAL to dlopen flags solves the problem for now. I have

> > I think this is a 'bug' in the code: you should NOT use RTLD_GLOBAL.
> > The correct flags are RTLD_NOW | RTLD_LOCAL.
> 
> When using RTLD_NOW | RTLD_LOCAL as default dlopen flags for Python it doesn't 
> work again.

Python is incorrectly built. You may have this
[excuse my terrible ASCII art .. ]:

	Python(exe+libs) --- + dlopen --> Cextension

That is wrong. It works on Unix due to design fault in Unix
linking. It should be:

	Python(stub exe) ---> linked ---> run-time library
	|                                     |
	+--- dlopen -- Cextension -- linked --+


I.e. Python executable AND the C extension module should be
linked against the run time library(s) which contain the whole
Python API.

On Unix you can statically link the RTL into the executable,
and dlopen-ed library will find symbols from the RTL in the
calling executable .. but this is WRONG. I'm not sure that
explains why you need to use RTLD_GLOBAL though.

But Python is *definitely* built incorrectly on my box:

$ ldd `which python`
        libpthread.so.0 => /lib/libpthread.so.0 (0x00002aeb41388000)
        libdl.so.2 => /lib/libdl.so.2 (0x00002aeb415a3000)
        libutil.so.1 => /lib/libutil.so.1 (0x00002aeb417a7000)
        libm.so.6 => /lib/libm.so.6 (0x00002aeb419aa000)
        libc.so.6 => /lib/libc.so.6 (0x00002aeb41c2c000)
        /lib64/ld-linux-x86-64.so.2 (0x00002aeb4116a000)

This is WRONG. Executables should never include an API which
is available to any dynamically loaded library. Python
SHOULD be linked against libpython.so. Note:

/usr/lib/python2.4/config/libpython2.4-pic.a
/usr/lib/python2.4/config/libpython2.4.a
/usr/lib/python2.4/config/libpython2.4.so
/usr/lib/libpython2.4.so.1.0
/usr/lib/libpython2.4.so.1
/usr/lib/python2.5/config/libpython2.5.a
/usr/lib/python2.5/config/libpython2.5-pic.a
/usr/lib/python2.5/config/libpython2.5.so

So these libs actually exist on Ubuntu for Python 2.4. Strangely,
only the 'config' ones for 2.5 (whatever they are).

Note there is one advantage of this scheme: a C extension will
use whatever API the executable was linked against.. but that
is the wrong way to do it.

Hmm.. I recall I ran into this bug myself. I wanted to allow
C++ exceptions in Python and that requires a C++ mainline.
The mainline of Python is only about 20 lines of code,
so it should be easy to just build a small C++ executable
and link against libpython.so.

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]