Based on my understanding, ltrace utility is used to trace library calls. I ltrace a simple program which calls printf only, but what the library function displayed is puts instead of printf. I am curious why it does not show printf but puts?
ltrace shows puts being called because it works on the binary file and the binary file calls puts.
Example: source:
#include <stdio.h>
int main(int c, char *v[])
{
printf("hello world\n");
}
Assembly:
.LC0:
.string "hello world"
main:
subq $8, %rsp
movl $.LC0, %edi
call puts
xorl %eax, %eax
addq $8, %rsp
ret
If you play with more examples, you may find that the compiler produces assembly code that calls memcpy when the source code does not, assembly code that does not call memcpy (or one of many other common functions) when the source code does, and so on. The compiler only needs to respect the meaning of the program, it does not need to respect the actual functions being called. Since printf and puts are standard functions that you are not allowed to redefine, it knows what these functions do and can replace one by the other if it deems it useful.
Here, puts was substituted to printf because puts is simpler (it does not interpret % formats and it is not variadic), and thus faster. The compiler was allowed to replace printf with puts in this case because printing the string did not require the interpretation of any format specifier, and the string happened to end in \n.
It is just an optimization. Compiler replaces printf("smth\n") with puts("smth") because the output is the same but puts() should work faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With