How to use the command ltrace (with examples)
- Linux
- December 25, 2023
Ltrace is a command-line utility that allows users to display dynamic library calls of a process. It can be used to trace function calls to dynamically linked libraries, including calls to malloc and free. This can be useful for debugging and profiling purposes.
Use case 1: Print (trace) library calls of a program binary
Code:
ltrace ./program
Motivation:
This use case is helpful when we want to analyze the library calls made by a program binary. By tracing the library calls, we can understand how the program interacts with the dynamically linked libraries and identify any potential issues or bottlenecks.
Explanation:
The command ltrace ./program
runs the ltrace
utility on the specified program binary. It prints a list of library calls made by the program during its execution.
Example output:
__libc_start_main(0x400550, 1, 0x7ffc136362d8, 0x400620 <unfinished ...>
printf("Hello, world!\n") = 14
exit(0 <unfinished ...>
+++ exited (status 0) +++
In this example, we can see that the program made a call to the printf
function and then exited successfully.
Use case 2: Count library calls. Print a handy summary at the bottom
Code:
ltrace -c path/to/program
Motivation:
Sometimes, we might want to know the frequency of library calls made by a program. Counting the library calls can help us identify the most frequently used functions, which can be useful for optimization or troubleshooting purposes.
Explanation:
The -c
flag tells ltrace
to count the library calls instead of simply printing them. By using this flag, ltrace
will print a summary at the bottom, showing the number of calls for each library function.
Example output:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
68.09 0.000013 13 1 open
30.06 0.000005 0 95 write
...
------ ----------- ----------- --------- --------- ----------------
100.00 0.000019 123 total
This output shows the number of times the open
and write
functions were called, along with the time spent in each function.
Use case 3: Trace calls to malloc and free, omit those done by libc
Code:
ltrace -e malloc+free-@libc.so* path/to/program
Motivation:
When we want to specifically trace calls to the malloc
and free
functions, but omit any calls made by the libc library, this use case becomes handy. It allows us to focus solely on memory allocation and deallocation calls made by the program.
Explanation:
The -e
flag is used to specify the library functions that we want to trace. In this case, we use malloc
and free
followed by -@libc.so*
to exclude any calls made to these functions within the libc library.
Example output:
malloc(16) = 0x7f1564fcf080
malloc(24) = 0x7f1564fcf0b0
malloc(32) = 0x7f1564fcf0e0
free(0x7f1564fcf080)
free(0x7f1564fcf0b0)
free(0x7f1564fcf0e0)
In this example, we can see the calls made to malloc
for allocating memory blocks and the corresponding calls to free
for deallocating the memory.
Use case 4: Write to file instead of terminal
Code:
ltrace -o file path/to/program
Motivation:
If we want to save the output of ltrace
to a file instead of displaying it on the terminal, we can use this use case. It allows us to retain the trace information for further analysis or examination.
Explanation:
The -o
flag followed by the filename specifies the file where we want to save the output of ltrace
. Using this flag ensures that the trace information is written to the specified file instead of being displayed on the terminal.
Example output:
ltrace: output written to file
In this example, the output of ltrace
is saved to the file specified, and the command confirms that the output has been successfully written to the file.
Conclusion:
The ltrace
command is a versatile tool for tracing dynamic library calls made by a program. It provides valuable insights into the interactions between a program and the dynamically linked libraries. By using its various options, such as counting function calls, filtering specific library calls, or saving the output to a file, users can gain a deeper understanding of program execution and diagnose potential issues.