Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ltrace printf() but shows puts()

Tags:

c

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?

like image 871
HuangJie Avatar asked Nov 18 '25 07:11

HuangJie


2 Answers

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.

like image 56
Pascal Cuoq Avatar answered Nov 19 '25 19:11

Pascal Cuoq


It is just an optimization. Compiler replaces printf("smth\n") with puts("smth") because the output is the same but puts() should work faster.

like image 38
Sergio Avatar answered Nov 19 '25 19:11

Sergio