Skip to content

Conversation

@jlebar
Copy link
Contributor

@jlebar jlebar commented Jan 18, 2013

... and invokes /data/python/bin/python.

Crucially, the wrapper script sets LD_PRELOAD=libpython2.7.so. Without
this, we can't load any of the libs in lib-dynload, which means that we
can't import any Python module which uses native code (e.g. the select
module).

Without LD_PRELOAD, we get an error like the following when we try to
import a module which uses native code:

import subprocess
Traceback (most recent call last):
File "", line 1, in
File "/data/python/lib/python2.7/subprocess.py", line 429, in
import select
ImportError: Cannot load library: reloc_library[1285]: 9814 cannot locate 'PyDict_Next'...

The root problem is that the lib-dynload libraries do not have an
explicit dependency on libpython.so (see readelf -d), so therefore the
bionic linker doesn't try to resolve their symbols against libpython.
Setting this dependency would be the Right Fix.

…les and invokes /data/python/bin/python.

Crucially, the wrapper script sets LD_PRELOAD=libpython2.7.so.  Without
this, we can't load any of the libs in lib-dynload, which means that we
can't import any Python module which uses native code (e.g. the select
module).

Without LD_PRELOAD, we get an error like the following when we try to
import a module which uses native code:

  >>> import subprocess
  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/data/python/lib/python2.7/subprocess.py", line 429, in <module>
    import select
  ImportError: Cannot load library: reloc_library[1285]:  9814 cannot locate 'PyDict_Next'...

The root problem is that the lib-dynload libraries do not have an
explicit dependency on libpython.so (see readelf -d), so therefore the
bionic linker doesn't try to resolve their symbols against libpython.
Setting this dependency would be the Right Fix.
You might want to pass an LD_LIBRARY_PATH to a child process of python, for example.
@jlebar
Copy link
Contributor Author

jlebar commented Jan 19, 2013

One problem with this is that any subprocesses launched by Python will have libpython2.7.so LD_PRELOADED into them. That's not strictly correct, as it will cause the linker to prefer pulling from libpython2.7 instead of the child processes' solibs.

But this is a small amount of breakage in comparison to not being able to import subprocess...

st3fan added a commit that referenced this pull request Jan 21, 2013
Add a |python| wrapper script which sets the right environment variables...
@st3fan st3fan merged commit 424f23e into st3fan:master Jan 21, 2013
@st3fan
Copy link
Owner

st3fan commented Jan 21, 2013

Thank you Justin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants