2

I want to replace libsqlite3 with the special version for Python. I have a special version of libsqlite3.so.0 /path/to/libsqlite3.so.0 and configured LD_LIBRARY_PATH. However, python's internal will not load it.

I checked and noticed the following:

  1. import sqlite3 loads python's original /usr/lib/python2.7/sqlite/__init__.py and dbapi2.py.
  2. dbapi2.py imports _sqlite, and this indicates /usr/lib/python2.7//lib-dynload/_sqlite3.so.
  3. _sqlite3.so always loads /usr/lib/i386-linux-gnu/libsqlite3.so.0, in spite of setting LD_LIBRARY_PATH.
  4. If I copy libpthread.so.0 to /path/to/libpthread.so.0, _sqlite3.so loads it. So, /path/to/libpthread.so.0 is loaded but /path/to/libsqlite3.so.0 is not loaded.

I want to know how to load /path/to/libsqlite3.so.0, a special version, without replacing /usr/lib/i386-linux-gnu/libsqlite3.so.0 (only with non-privileged permission).

1 Answer 1

6

You might try to force loading of the lib with:

LD_PRELOAD=/path/to/libsqlite3.so.0 python ...

The library will be loaded in memory when python will be executed. So normally when _sqlite3 module will be imported, it will not load libsqlite3.so.0, and use the version already preloaded in memory.

Edit

The LD_LIBRARY_PATH doesn't work in that case cause libsqlite3.so.0 is loaded by _sqlite.so module, loaded by dlopen() within Python. In that case, the manpage of dlopen() said that the order is:

  1. (ELF only) If the executable file for the calling program contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the directories listed in the DT_RPATH tag are searched.

  2. If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched. (As a security measure this variable is ignored for set-user-ID and set-group-ID programs.)

  3. ...

So if an DT_RPATH is set on the binary, it will be taken prior to your LD_LIBRARY_PATH.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, it works but do I have to use LD_PRELOAD? Setting LD_LIBRARY_PATH will work to replace libpthread.so.0 but not to replace libsqlite3.so.0. I'm bothered by this fact. What is the difference between two libraries?
libpthread.so.0 is loaded by python itself (check ldd /usr/bin/python2.7) while libsqlite3.so.0 is loaded by _sqlite.so, loaded itself by dlopen() in Python. I don't know why LD_LIBRARY_PATH doesn't work in that case. Maybe cause of rpath in _sqlite.so ?
That's cause of the rpath, check the manpage of dlopen(), the priority order is explained: 1. rpath, 2. LD_LIBRARY_PATH, 3. runpath, ...
I succeeded to load my original one with only setting LD_LIBRARY_PATH, by copying _sqlite3.so to /path/to and chrpath --delete /path/to/_sqlite3.so to remove rpath information from it. So many thanks to you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.