Are you interested in fixing those library bugs and bugs you see when installing a cool new program on Linux?? Check out this article which shows how to use ltrace and provides you with the necessary tool to debug library calls.
What is a Library?
Most people are familiar with .dll/.DLL
records (dynamic link libraries) in Windows. The identical Linux is a .so
file, a shared object, often referred to simply as a library.
A library can be used by an application that enables that program to use functionalities external to its program code.. As an example, a web server may want to use a library of E / S disk written by the operating system vendor or other third party. It is a way of sharing common goods and interests in the majority, if not in all, operating systems.
Libraries can be dynamically loaded at runtime (when the calling program is starting, as an example) or they can be compiled into a target application / tracks. It is because of that, will always load (whether they are used or not), as part of and as long as the application that has them compiled is started / integrated.
For more information on libraries, its dependencies and ldd
tool, you may want to read regarding how to work with shared object dependencies in linux. the ldd
is another useful tool to have in any more advanced Linux user toolbox.
What is it draw?
There are several trace utilities in Linux, as strace to track system calls and signals and the traceroute
to trace network routing. the ltrace
Utility / tool tracks all library calls.
If you have read our work with shared object dependencies (library) in the Linux article (linked above), You have already seen how you can find out which libraries a particular binary is bound to using the ldd
tool. The purpose and functionality of ltrace
it's something different; very in line with strace
, the ltrace
The command tracks all library calls that a particular program makes while running.
Equal to strace
, we can start a program below (think of it as a hierarchy) ltrace
. We simply specify the program that ltrace
should start as the first choice for ltrace
, and ltrace
will start that program for us and immediately start (on a higher level) to track all calls to any library (operating system or third party installed).
It does this by intercepting and recording the dynamic library calls made by the running program. At the same time it will track any signal sent to the running program, very identical to strace
(and, if you wish, this functionality can be disabled by specifying the -b
or identical --no-signals
option a ltrace
).
Note that the term dynamic is of great importance here; ltrace
will trace calls to external libraries (in the form of .so
O .a
records), in other words, libraries not compiled directly into a program; dynamic Libraries. It is because of that, if you have a binary with libraries statically (compiled), ltrace
will not be able to see / trace such internal calls.
installing draw
Install draw on your Debian-based Linux distribution / Apt (like Ubuntu and Mint), run the following command in your terminal:
sudo apt install ltrace
Install draw on your RedHat-based Linux distribution / Yum (like RHEL, Centos and Fedora), run the following command in your terminal:
sudo yum install ltrace
Usando ltrace
Configuremos un pequeño entorno de prueba:
sudo apt install tar xz-utils mkdir ~/workspace && cd ~/workspace touch a b c
Aquí instalamos tar
and xz
instalando xz-utils
(puedes usar sudo yum install tar xz
instead, si está usando Centos / RHEL / Fedora). A continuación creamos un directorio ~/workspace
y saltó a él. Posteriormente hicimos tres archivos vacíos usando el touch
command, namely, records a
, b
and c
.
Comencemos comprimiendo nuestros tres archivos en un (tar combinado y xz comprimido) archive.tar.xz
file, mientras se ejecuta el mismo bajo ltrace
, y observando el ltrace
production:
ltrace tar -hcf --xz archive.tar.xz *
We only see a small amount of output. We can see that our program ended successfully (archive file created), in other words, status 0
: an exit code of 0
always means success on Linux (even though the program needs to have exit codes implemented correctly).
This is not very useful so far. Reason for a few seconds regarding how tar
will operate here will quickly reveal our next approach. The avid reader at the same time may have understood that the tar
The command would internally call the xz
command. the --xz
option passed to our tar
command line will ensure that the xz
The program is used for compression.
The secondary procedure (or the third in the general hierarchy) in other words xz
(hierarchy: ltrace
> tar
> xz
) will be started by tar
when necessary. As such, we need to trace the child processes of the program running under ltrace
, in other words tar
. We can do this by specifying the following (-f
) option a ltrace
:
ltrace -f tar -hcf --xz archive.tar.xz *
Note that it is essential to specify the -f
option directly behind ltrace
and no later on the command line after tar
as an example. The reason is that we want to specify this option for ltrace
and not to tar
command. All alternatives after tar
command are tar
specific options while -f
is a specific alternative for ltrace
.
The result is a little more interesting. We still haven't seen any calls to the library (no way), but at least we see that two threads are forked (note exec()
) and that both threads end with status 0
. Practical and all good.
Then, ¿dónde están las llamadas de nuestra biblioteca? Comprobación tar
and xz
(los dos programas que utilizará el comando para crear el archivo de almacenamiento) with ldd
, nos damos cuenta rápidamente de que la mayoría de las bibliotecas que usan ambos programas son bibliotecas del sistema:
whereis tar
whereis xz
ldd /bin/tar
ldd /usr/bin/xz
It is because of that, debemos ir un paso más allá y habilitar el seguimiento de las llamadas a la biblioteca del sistema especificando el -S
option a ltrace
. Esta opción se encuentra deshabilitada / apagada de forma predeterminada, dado que la salida se volvería un poco detallada, y es probable que se asuma que las bibliotecas del sistema son de forma general mucho más estables y, as such, no es necesario rastrearlas para comenzar. Let's take a look.
ltrace -fS tar -hcf --xz archive.tar.xz *
O, con fines de prueba:
ltrace -fS tar -hcf --xz archive.tar.xz * 2>&1 | head -n10 ltrace -fS tar -hcf --xz archive.tar.xz * 2>&1 | tail -n10
Como el resultado fue sustancial, we had to capture the first and last ten lines using a head
and tail
command. In order to use these commands we had to redirect stderr
for stdout
using the 2>&1
redirect like ltrace
will report by default about stderr
. If you are interested in learning more about redirection, consulte Bash Automation and Scripting Basics (Part 3).
Now that we add the -S
option, we can see all the libraries that are accessed. As an example, we see /etc/ld.so.preload
being accessed. The output is sequential (from top to bottom), so if there are other events (branching thread, etc.) in the middle, these will be displayed online the moment they take place. At the same time we could add the -t
option for time-based output:
Ending
In this article, we present and discuss the versatile ltrace
program, which is a great tool that makes it possible to trace all the dynamic library calls that a given program makes. We installed ltrace
, set up a test environment and ran some ltrace
commands with the most used alternatives.