How to view hierarchy of shared library dependencies using lddtree

Tree of library dependencies shown by lddtree
Tree of library dependencies shown by lddtree

ldd is one of the key tools that should be familiar to all programmers. It shows the list of all shared libraries that an executable binary depends on.

A binary, say ELF file, lists only the immediate shared libraries it depends on in its header. Each of these shared libraries could further depend on other libraries and so on. It would be very useful if you could see the hierarchical tree of these dependencies between the shared libraries. Thankfully, there is a tool that does exactly that named lddtree.

  • It can be installed easily:
$ sudo apt install pax-utils
  • Usage is straightforward:
$ lddtree foo
  • By default, the tool does not show duplicated dependencies. That is, the dependency between a library A and B is shown only once and skipped after that, though it may occur many times. To view all the dependencies, including duplicates:
$ lddtree -a foo

Beware that this can result in a very big tree! This is because dependencies like libc, the ld-linux loader and such will appear for almost all shared libraries.

Note: The Dependency Walker tool does something similar on Windows and can be used as described here.

Tried with: PaX-Utils 0.2.3 and Ubuntu 14.04

Advertisements

ELF Library Viewer

Dependency Walker is a popular tool on Windows to view the dependent modules of a EXE or DLL file. ELF Library Viewer is a similar program for Linux. It shows the tree of shared libraries that a program or shared library is dependent on.

The source code of ELF Library Viewer can be downloaded here. It can be compiled easily by typing cmake followed by make.

Tried with: ELF Library Viewer 0.9 and Ubuntu 12.04 LTS

Error: The application was unable to start correctly

Problem

Executing some programs of your own creation can sometimes result in the craziest errors. Here is an error that I face sometimes:

The error message:

The application was unable to start correctly (0xc0000013). Click OK to close the application.

Showing no clues to solve it and throwing a random error number (or is it an address) like 0xc0000013 this one is a real mystery!

Solution

I have found that this error message typically occurs when something is wrong with the DLL files being loaded by the executable at runtime. I use the awesome Dependency Walker to load the program and find the underlying cause.

For example, I found that I had placed x64 DLL files in the directory of a x86 executable. On running this executable, I was getting this error. On replacing those files with x86 DLL files, the executable loaded fine.

Dependency Walker

The Dependency Walker is a great utility to figure out DLL problems. Here is a simple illustration of its use.

I was recently working on code shared by a friend. The C++ code compiled fine under Visual Studio 2010, but when executed would pop up this error message:

The error message:

The program can’t start because MSVCR80.dll is missing from your computer. Try reinstalling the program to fix this problem.

I dissected MSVCR80.dll as MS (Microsoft) VCR (Visual C Runtime) 80 (Visual Studio 2005) library.

The age old Windows trick of getting MSVCR80.dll from some other computer and putting it in the directory of the .exe did not work. This is because Windows now ships with a SxS system to maintain DLLs of various versions. This requires manifest files and other complicated machinery to work.

Installing the Windows 7 Platform SDK, the older Windows Server 2003 Platform SDK and Visual C++ 2005 Redistributable packages did not work either.

Having no further clue to this problem, I decided to use Dependency Walker. Execute the depends.exe and open the .exe which is throwing the error.

Dependency Walker immediately found the 3 DLLs which were causing problems. These are displayed in red in the middle pane:

To figure out the origin of the use of these DLLs, right-click on any of the problematic DLL in the middle pane and choose Highlight matching module in tree. This shows the origin of the problem in the dependency tree displayed in the top pane:

Bingo! So, a third party DLL named ILMIMF.dll that was linked with the C++ code was the cause of the error. Rebuilding this DLL separately from its source code and relinking the rest of the project fixed the error.