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