iksemyonov
iksemyonov

Reputation: 4196

Is it possible to know which library pulled in another one using ldd?

Once an application has been linked with the dynamic libraries it requires, is it possible to find out which exact library has pulled in another one that I'm seeing in the list?

For example, today I had a situation where a library that shouldn't have been there at all in the first place was present in the ldd output, and was crashing the application. By logical deduction, I could figure it out and isolate the problem, then rebuild the respective project to not include the faulty lib anymore. But is it possible to do the same without any additional knowledge about the application and the libraries it depends on, using an exterrnal tool from the likes of ldd? (The problem was that the library in question wasn't being used directly by the application, rather by another library that the application was linking to directly.)

In essence, it looks like I'm searching for a way to restore the linking dependency graph once the application has been linked together.

Upvotes: 3

Views: 2419

Answers (3)

coolparadox
coolparadox

Reputation: 518

ldd is ultimately a wrapper script for executing the dynamic linker/loader with variable LD_TRACE_LOADED_OBJECTS set in environment. For example the following command outputs the same as ldd /bin/ls in my system:

user@localhost ~ $ LD_TRACE_LOADED_OBJECTS=1 /lib/ld-linux.so.* /bin/ls
    linux-gate.so.1 (0xb77bd000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7798000)
    libc.so.6 => /lib/libc.so.6 (0xb75ef000)
    libattr.so.1 => /lib/libattr.so.1 (0xb75e9000)
    /lib/ld-linux.so.2 (0x80065000)

There is a plethora of other environment variables for tuning the dynamic linker documented in ld.so(8) manpage. One of particular interest for discovering the reason a specific library was pulled is LD_DEBUG=files, that traces what files the linker goes after during processing of the executable:

user@localhost ~ $ LD_TRACE_LOADED_OBJECTS=1 LD_DEBUG=files /lib/ld-linux.so.* /bin/ls
     27831: file=/bin/ls [0];  generating link map
     27831:   dynamic: 0x08064f0c  base: 0x00000000   size: 0x0001e034
     27831:     entry: 0x0804bffc  phdr: 0x08048034  phnum:         10
     27831: 
     27831: 
     27831: file=libacl.so.1 [0];  needed by /bin/ls [0]
     27831: file=libacl.so.1 [0];  generating link map
     27831:   dynamic: 0xb772ced8  base: 0xb7724000   size: 0x0000917c
     27831:     entry: 0xb77257f0  phdr: 0xb7724034  phnum:          7
     27831: 
     27831: 
     27831: file=libc.so.6 [0];  needed by /bin/ls [0]
     27831: file=libc.so.6 [0];  generating link map
     27831:   dynamic: 0xb771fda4  base: 0xb757b000   size: 0x001a8eac
     27831:     entry: 0xb75937b0  phdr: 0xb757b034  phnum:         11
     27831: 
     27831: 
     27831: file=libattr.so.1 [0];  needed by /lib/libacl.so.1 [0]
     27831: file=libattr.so.1 [0];  generating link map
     27831:   dynamic: 0xb7579ef0  base: 0xb7575000   size: 0x000050bc
     27831:     entry: 0xb7575ed0  phdr: 0xb7575034  phnum:          7
     27831: 
    linux-gate.so.1 (0xb7749000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7724000)
    libc.so.6 => /lib/libc.so.6 (0xb757b000)
    libattr.so.1 => /lib/libattr.so.1 (0xb7575000)
    /lib/ld-linux.so.2 (0x80094000)

In the above example, we see that libacl.so.1 and libc.so.6 were required by /bin/ls itself, and libattr.so.1 was pulled as a requirement of libacl.so.1.

Upvotes: 6

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

Run ldd on each of the libraries reported by ldd executable. Continue recursively until the culprit is found.

Alternatively, run

objdump -p /path/to/program-or-library | grep NEEDED

recursively.

Upvotes: 2

SergeyA
SergeyA

Reputation: 62563

To know this you will have to use readelf recursively. First run it on your executable, and look for NEEDED libraries. This will tell you what your executable needs directly. After that you should iteratively repeat the process for every library which is needed, and once you arrive at the library in question you will know the inclusion path.

Upvotes: 1

Related Questions