Search code examples
gccgdbprintf

printf compiler optimization? can't find "%s" characters in gdb on the stack


When my program is disassembled in gdb, I can see the address of buf be pushed onto the stack, but I don't see the format string pushed onto it. Any reason why this is? Is it a clever compiler optimization?

I've tried compiling a few different variations of printf statements to see if I could mimic the "%s" string (or address of it) not being pushed onto the stack, but I couldn't do it.

This is the program code:

int main(int argc, char **argv) {

    char buf[128];
    if(argc < 2) return 1;

    strcpy(buf, argv[1]);

    printf("%s\n", buf);

    return 0;
}

compiled with gcc 4.5.2, 32 bit linux


Solution

  • Yes, it appears that gcc will throw away "printf ("%s\n", buff)" and substitute "puts()" in its place:

    vi tmp.c =>
    
    #include <stdio.h>
    #include <string.h>
    
    int
    main(int argc, char **argv)
    {
        char buf[128];
        if(argc < 2)
          return 1;
    
        strcpy(buf, argv[1]);
        printf("%s\n", buf);
    
        return 0;
    }
    

    $ gcc -S -Wall -pedantic tmp.c less tmp.s =>

            .file   "tmp.c"
            .text
    .globl main
            .type   main, @function
    main:
            leal    4(%esp), %ecx
            andl    $-16, %esp
            pushl   -4(%ecx)
            pushl   %ebp
            movl    %esp, %ebp
            pushl   %ecx
            subl    $148, %esp
            movl    %ecx, -140(%ebp)
            movl    -140(%ebp), %eax
            cmpl    $1, (%eax)
            jg      .L2
            movl    $1, -136(%ebp)
            jmp     .L4
    .L2:
            movl    -140(%ebp), %edx
            movl    4(%edx), %eax
            addl    $4, %eax
            movl    (%eax), %eax
            movl    %eax, 4(%esp)
            leal    -132(%ebp), %eax
            movl    %eax, (%esp)
            call    strcpy
            leal    -132(%ebp), %eax
            movl    %eax, (%esp)
            call    puts
            movl    $0, -136(%ebp)
    .L4:
            movl    -136(%ebp), %eax
            addl    $148, %esp
            popl    %ecx
            popl    %ebp
            leal    -4(%ecx), %esp
            ret
            .size   main, .-main
            .ident  "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-48)"
            .section        .note.GNU-stack,"",@progbits