在 Python 上加载 libsqlite3.so

Tom*_*abe 1 python sqlite

我想libsqlite3用 Python 的特殊版本替换。我有一个特殊版本libsqlite3.so.0 /path/to/libsqlite3.so.0并配置了LD_LIBRARY_PATH. 但是,python 的内部不会加载它。

我检查并注意到以下几点:

  1. import sqlite3加载 python 的原始/usr/lib/python2.7/sqlite/__init__.pydbapi2.py.
  2. dbapi2.py进口_sqlite,这表明/usr/lib/python2.7//lib-dynload/_sqlite3.so
  3. _sqlite3.so总是加载/usr/lib/i386-linux-gnu/libsqlite3.so.0,尽管设置LD_LIBRARY_PATH
  4. 如果我复制libpthread.so.0/path/to/libpthread.so.0,则_sqlite3.so加载它。因此,/path/to/libpthread.so.0已加载但未/path/to/libsqlite3.so.0加载。

我想知道如何加载/path/to/libsqlite3.so.0一个特殊版本而不替换/usr/lib/i386-linux-gnu/libsqlite3.so.0(仅具有非特权许可)。

tit*_*ito 5

您可以尝试使用以下命令强制加载 lib:

LD_PRELOAD=/path/to/libsqlite3.so.0 python ...
Run Code Online (Sandbox Code Playgroud)

执行 python 时,库将加载到内存中。所以通常在_sqlite3导入模块时,不会加载libsqlite3.so.0,而是使用内存中已经预加载的版本。

编辑

LD_LIBRARY_PATH 在这种情况下不起作用,因为 libsqlite3.so.0 由 _sqlite.so 模块加载,由 Python 中的 dlopen() 加载。在这种情况下,dlopen() 的联机帮助页说顺序是:

  1. (仅限 ELF)如果调用程序的可执行文件包含 DT_RPATH 标记,但不包含 DT_RUNPATH 标记,则搜索 DT_RPATH 标记中列出的目录。

  2. 如果在程序启动时将环境变量 LD_LIBRARY_PATH 定义为包含以冒号分隔的目录列表,则搜索这些目录。(作为安全措施,set-user-ID 和 set-group-ID 程序将忽略此变量。)

  3. ...

因此,如果在二进制文件上设置了 DT_RPATH,它将在您的 LD_LIBRARY_PATH 之前被采用。