检查共享库中的非默认加载器 [英] checking shared libraries for non default loaders

查看:90
本文介绍了检查共享库中的非默认加载器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ldd是检查给定可执行文件正在使用或将要使用的共享库的简单好方法.但是,它并不总是能按预期工作.例如,请参见下面的shell片段,该片段演示了如何失败"将libreadline"dependency"发现到python二进制文件中

ldd is a good simple way to check for shared libraries a given executable is or will be using. However it does not always work as expected. For example, see the following shell snippet that demonstrates how it "fails" to found the libreadline "dependency" into the python binary

我尝试了许多其他发行版,但我是从Tikanga复制

I've tried many other distributions, but I'm copying from Tikanga

$ lsb_release -a
LSB Version:    :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Release:        5.6
Codename:       Tikanga

查看ldd对默认安装的python(来自官方存储库)的作用.

See what ldd does on the default installed python (from official repositories).

$ which python
/usr/bin/python
$ ldd `which python`
    libpython2.4.so.1.0 => /usr/lib64/libpython2.4.so.1.0 (0x00000030e6200000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e0e00000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000030e0a00000)
    libutil.so.1 => /lib64/libutil.so.1 (0x00000030ee800000)
    libm.so.6 => /lib64/libm.so.6 (0x00000030e0600000)
    libc.so.6 => /lib64/libc.so.6 (0x00000030e0200000)
    /lib64/ld-linux-x86-64.so.2 (0x00000030dfe00000)
$ ldd `which python` | grep readline
$

没有发现有关readline的信息.现在,我确实从交互式用法中知道该二进制文件确实具有实时功能,所以不要尝试查看它的来源.

Nothing found about readline. Now I do know from interactive usage that this binary does have realine functionality, so let't try to see where it's coming from.

$ python &
[1] 21003
$ Python 2.4.3 (#1, Dec 10 2010, 17:24:35) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

[1]+  Stopped                 python

在后台启动了一个交互式python会话(pid 21003)

Started an interactive python session in background (pid 21003)

$ lsof -p 21003
COMMAND   PID    USER   FD   TYPE DEVICE     SIZE    NODE NAME
python  21003 ddvento  cwd    DIR   0,33    16384  164304 /glade/home/ddvento/loader-test
python  21003 ddvento  rtd    DIR    8,3     4096       2 /
python  21003 ddvento  txt    REG    8,3     8304 6813419 /usr/bin/python
python  21003 ddvento  mem    REG    8,3   143600 8699326 /lib64/ld-2.5.so
python  21003 ddvento  mem    REG    8,3  1722304 8699327 /lib64/libc-2.5.so
python  21003 ddvento  mem    REG    8,3   615136 8699490 /lib64/libm-2.5.so
python  21003 ddvento  mem    REG    8,3    23360 8699458 /lib64/libdl-2.5.so
python  21003 ddvento  mem    REG    8,3   145824 8699445 /lib64/libpthread-2.5.so
python  21003 ddvento  mem    REG    8,3   247544 6821551 /usr/lib64/libreadline.so.5.1
python  21003 ddvento  mem    REG    8,3    15840 8699446 /lib64/libtermcap.so.2.0.8
python  21003 ddvento  mem    REG    8,3  1244792 6833317 /usr/lib64/libpython2.4.so.1.0
python  21003 ddvento  mem    REG    8,3    18152 8699626 /lib64/libutil-2.5.so
python  21003 ddvento  mem    REG    8,3 56446448 6832889 /usr/lib/locale/locale-archive
python  21003 ddvento  mem    REG    8,3    21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so
python  21003 ddvento  mem    REG    8,3    25464 6901074 /usr/lib64/gconv/gconv-modules.cache
python  21003 ddvento    0u   CHR  136,1                3 /dev/pts/1
python  21003 ddvento    1u   CHR  136,1                3 /dev/pts/1
python  21003 ddvento    2u   CHR  136,1                3 /dev/pts/1
$ lsof -p 21003 | grep readline
python  21003 ddvento  mem    REG    8,3   247544 6821551 /usr/lib64/libreadline.so.5.1
python  21003 ddvento  mem    REG    8,3    21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so

宾果!这是readline!

Bingo! Here it is readline!

但是,此技术仅在有效加载库后才有效,例如,直到python进程未运行from Tkinter import *

However, this technique works only when the library is effectively loaded, so for example it does not find /usr/lib64/libtcl8.4.so until the python process does not run something like from Tkinter import *

所以我有两个问题:

  1. 我相信ldd的问题在于它假设使用了标准加载程序,而python很可能正在使用其自己的特殊加载程序(因此您不必每次都重新链接可执行文件安装一个新的python模块,该模块不是纯python,而是具有一些c/c ++/fortran代码).这是正确的吗?

  1. I believe the problem with ldd is that it assumes the usage of the standard loader, whereas very likely python is using its own special loader (so that you don't have to relink the executable every time you install a new python module that is not pure python but has some c/c++/fortran code). Is this correct?

很显然,如果一个可执行文件正在使用其自己的加载程序,则如何找到该可执行文件可能加载的所有可能的库"这一问题没有明显的答案:这取决于加载程序的工作.但是有没有办法找出python可以加载哪些库?

Clearly, if an executable is using its own loader, there is no obvious answer to the question "how to find all the possible libraries this executable may load": it depends on what the loader does. But is there a way to find out what libraries may be loaded by python?

PS:与1相关.如果您着眼于这个问题,您应该已经知道以下内容,但是如果不了解,您应该:完全弄乱ldd输出(将其仅部分弄乱是很简单的)是多么简单.有点困难):

PS: related to 1. If you are landing on this question you should already know the following, but if don't you should: see how simple is to completely mess up ldd output (messing it up only partially is a little harder):

$ cat hello.c 
#include <stdio.h>

int main() {
  printf("Hello world.\n");
  return 0;
}

$ gcc -static hello.c -o loader
$ gcc -Wl,--dynamic-linker,./loader hello.c -o hello
$ ./hello 
Hello world.
$ ldd ./hello
Hello world.

推荐答案

Python,Perl和其他解释型语言确实使用dlopen()动态加载内容. (这与替换标准加载器不同;他们仍在使用它,实际上dlopen()是对基于ELF的系统上标准加载器的一个钩子.)

Python, Perl, and other interpreted languages do load things dynamically using dlopen(). (This is not the same thing as replacing the standard loader; they are still using that, and in fact dlopen() is a hook into the standard loader on ELF-based systems.)

没有可加载模块的标准注册表. Python使用自己的规则来确定可从何处加载扩展模块(请参见sys.path),包括那些具有关联共享对象的模块. Perl使用不同的规则. Apache使用的规则仍然不同,等等.

There is no standard registry for loadable modules. Python uses its own rules to determine where extension modules can be loaded from (look at sys.path), including those which have associated shared objects. Perl uses different rules. Apache uses still different rules, etc.

因此,总结一下您的问题的答案:

So to summarize the answers to your questions:

  1. 不完全

  1. not exactly

这篇关于检查共享库中的非默认加载器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆