Иерархический лдд (1)

Из-за использования Gentoo часто случается, что после обновления программы связываются со старыми версиями библиотек. Обычно revdep-rebuild помогает решить эту проблему, но на этот раз это зависимость от библиотеки Python, и python-updater не подниму

Есть ли "иерархический" вариант ldd который показывает мне, какая разделяемая библиотека зависит от какой другой разделяемой библиотеки? В большинстве случаев библиотеки и исполняемые файлы связаны только с несколькими другими общими библиотеками, которые, в свою очередь, были связаны с несколькими другими, превращая зависимость библиотеки в большой список. Я хочу знать, какую зависимость я должен перестроить с помощью новой версии другой библиотеки, которую я обновил.

4 ответа

Решение

Если вы используете Portage≥2.2 с FEATURES=preserve-libs, вам редко нужно revdep-rebuild уже как старый .so. Версии будут сохранены по мере необходимости (хотя вам все равно нужно тщательно перестраивать, так как материал все еще идет kaboom, когда libA.so.0 хочет libC.so.0 а также libB.so.0 хочет libC.so.1 и какой-то двоичный файл хочет оба libA.so.0 а также libB.so.0).


Как говорится, что ldd делает, чтобы заставить динамический компоновщик загружать исполняемый файл или библиотеку, как это обычно делается, но распечатывает некоторую информацию по пути. Это рекурсивный поиск "бинарная библиотека нуждается в другой библиотеке & hellip", потому что это то, что делает динамический компоновщик.

В настоящее время я использую Linux / ppc32; в Linux / x86 динамический компоновщик обычно /lib/ld-linux.so.2 и в Linux / x86_64 динамический компоновщик обычно /lib/ld-linux-x86-64.so.2, Здесь я называю это непосредственно, чтобы забить точку, что все ldd это не что иное, как сценарий оболочки, который вызывает динамический компоновщик для выполнения своей магии.

$ /lib/ld.so.1 / sbin / badblocks
Использование: /sbin/badblocks [-b block_size] [-i входной_файл] [-o выходной_файл] [-svwnf]
       [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]
       [-p num_passes] [-t test_pattern [-t test_pattern [...]]]
       устройство [last_block [first_block]]
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks
        linux-vdso32.so.1 =>  (0x00100000)
        libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
        libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
        libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
        /lib/ld.so.1 (0x48000000)
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2
        linux-vdso32.so.1 =>  (0x00100000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000)
        libc.so.6 => /lib/libc.so.6 (0x6fe18000)
        /lib/ld.so.1 (0x203ba000)
$ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2
/lib/libcom_err.so.2

/sbin/badblocks не перечисляет libpthread.so.0 как зависимость от библиотеки, но она втягивается libcom_err.so.2,

Ваша проблема в том, что ldd не выводит красивое дерево зависимостей? использование ldd -v,

$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /lib/ld.so.1 /sbin/badblocks
        linux-vdso32.so.1 =>  (0x00100000)
        libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
        libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
        libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
        /lib/ld.so.1 (0x201f9000) Информация о версии:
        /sbin/badblocks:
                libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
        /lib/libext2fs.so.2:
                libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.3) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
        /lib/libcom_err.so.2:
                ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
                libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0
                libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0
                libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
        /lib/libc.so.6:
                ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
                ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
        /lib/libpthread.so.0:
                ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
                ld.so.1 (GLIBC_2.1) => /lib/ld.so.1
                ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
                libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6
                libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 

Если вы хотите, вы можете читать заголовки ELF напрямую, а не в зависимости от динамического компоновщика.

$ readelf -d / sbin / badblocks | ГРЕП НУЖЕН
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [libext2fs.so.2]
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [libcom_err.so.2]
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [libc.so.6]
$ readelf -d /lib/libcom_err.so.2 | ГРЕП НУЖЕН
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [libpthread.so.0]
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [libc.so.6]
 0x00000001 (НЕОБХОДИМО) Общая библиотека: [ld.so.1]

Вы также можете man ld.so за другие милые трюки, с которыми можно играть glibc Динамический компоновщик.

Я вижу много интересных деталей, но нет прямого ответа на заданный вопрос.

"Иерархическая" версия ldd является lddtree (от app-misc/pax-utils):

$ lddtree /usr/bin/xmllint 
xmllint => /usr/bin/xmllint (interpreter => /lib64/ld-linux-x86-64.so.2)
    libreadline.so.6 => /lib64/libreadline.so.6
        libncurses.so.5 => /lib64/libncurses.so.5
            libdl.so.2 => /lib64/libdl.so.2
    libxml2.so.2 => /usr/lib64/libxml2.so.2
        libicui18n.so.49 => /usr/lib64/libicui18n.so.49
            libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libstdc++.so.6
                ld-linux.so.2 => /lib64/ld-linux.so.2
            libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libgcc_s.so.1
        libicuuc.so.49 => /usr/lib64/libicuuc.so.49
        libicudata.so.49 => /usr/lib64/libicudata.so.49
        libz.so.1 => /lib64/libz.so.1
        liblzma.so.5 => /usr/lib64/liblzma.so.5
        libm.so.6 => /lib64/libm.so.6
    libpthread.so.0 => /lib64/libpthread.so.0
    libc.so.6 => /lib64/libc.so.6

Мне нужно было что-то вроде этого, поэтому я написал tldd здесь он показывает свои собственные зависимости библиотеки:

$./tldd./tldd./tldd
Li─libstdC++. So.6 => /lib64/libstdc++.so.6 (0x0000003687c00000)
  ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000)
  │ └─libc.so.6 => /lib64/libc.so.6 (0x0000003684c00000)
  │   └─ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003684400000)
  └─libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003686c00000)

Я также собирался предложить "readelf -d", но также убедиться, что вы строите с LDFLAGS="-Wl,- по мере необходимости", если вы этого еще не сделали. Это заставит вас реже сталкиваться с этой проблемой. Preserve-libs в Portage 2.2 хороши, но я полагаю, что это было замаскировано в первую очередь из-за этого - у него есть недостатки.

Другие вопросы по тегам