проверка разделяемых библиотек на наличие загрузчиков не по умолчанию

ldd— это хороший простой способ проверить общие библиотеки, которые данный исполняемый файл использует или будет использовать. Однако это не всегда работает так, как ожидалось. Например, см. следующий фрагмент оболочки, демонстрирующий, как «не удается» найти «зависимость» libreadline в бинарном файле python

Я пробовал много других дистрибутивов, но я копирую из 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(из официальных репозиториев).

$ 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 ничего не найдено. Теперь я знаю из интерактивного использования, что у этого двоичного файла есть реальная функциональность, так что давайте не будем пытаться понять, откуда она взялась.

$ 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.)

$ 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

Бинго! Вот это читлайн!

Однако этот метод работает только тогда, когда библиотека эффективно загружена, поэтому, например, она не находит /usr/lib64/libtcl8.4.soдо тех пор, пока процесс python не запустит что-то вродеfrom Tkinter import *

Итак, у меня есть два вопроса:

  1. Я считаю, что проблема с lddзаключается в том, что он предполагает использование стандартного загрузчика, в то время как python, скорее всего, использует свой собственный специальный загрузчик (, так что вам не нужно повторно связывать исполняемый файл каждый раз, когда вы устанавливаете новый модуль python, который не чистый python, но есть код c/c++/fortran). Это правильно?

  2. Очевидно, что если исполняемый файл использует собственный загрузчик, нет очевидного ответа на вопрос «как найти все возможные библиотеки, которые может загрузить этот исполняемый файл»:, это зависит от того, что делает загрузчик. Но есть ли способ узнать, какие библиотеки могут быть загружены python?

PS:относится к 1. Если вы приземлились на этот вопрос, вы уже должны знать следующее:но если нет, вы должны:увидеть, как просто полностью испортить lddвывод (испортить его только частично немного сложнее):

$ 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.
8
задан Davide 20 April 2012 в 20:31
поделиться