Due to using Gentoo, it often happens that after an update programs are linked against old versions of libraries. Normally, revdep-rebuild helps resolving that, but this time it’s a dependency on a python library, and python-updater won’t pick it up.
Is there a “hierarchical” variant of ldd which shows me what shared library depends on which another shared library? Most of the time libraries and executables are linked only against a handful of other shared libraries, which in turn were linked against a handful, turning the library dependency into a big list. I want to know which dependency I’ve got to rebuild with the new version of another library that I upgraded.
If you are running Portage≥2.2 with
FEATURES=preserve-libs, you should rarely ever needrevdep-rebuildanymore as old.so.vers will be preserved as needed (though you still need to rebuild carefully, as stuff still goes kaboom whenlibA.so.0wantslibC.so.0andlibB.so.0wantslibC.so.1and some binary wants bothlibA.so.0andlibB.so.0).That being said, what
ldddoes is to get the dynamic linker to do load the executable or library as it usually would, but print out some info along the way. This is a recursive “binary needs library needs other library&hellip” search, because that’s what the dynamic linker does.I’m currently running Linux/ppc32; on Linux/x86, the dynamic linker is usually
/lib/ld-linux.so.2, and on Linux/x86_64, the dynamic linker is usually/lib/ld-linux-x86-64.so.2. Here, I call it directly just to hammer in the point that alllddis nothing more than a shell script that calls upon the dynamic linker to perform its magic.$ /lib/ld.so.1 /sbin/badblocks Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf] [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks] [-p num_passes] [-t test_pattern [-t test_pattern [...]]] device [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/badblocksdoesn’t listlibpthread.so.0as a library dependency, but it gets pulled in bylibcom_err.so.2.Is your problem that
ldddoesn’t output a nice-looking dependency tree? Useldd -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) Version information: /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.6If you want, you can read the ELF headers directly instead of depending on the dynamic linker.
You can also
man ld.sofor other cute tricks you can play withglibc‘s dynamic linker.