简体   繁体   中英

Why Linux does not crash but output an random string?

char* getChar()
{
    //char* pStr = "TEST!!!";
    char str[10] = "TEST!!!";
    return str;
}
int main(int argc, char *argv[])
{
    double *XX[2];

    printf("STR is %s.\n", getChar());
    return (0);
}

I know a temporary variable in a stack SHOULD not be returned.

Actually it will output a undecided string.

When does Linux crash except NULL-Pointer-Reference?

You've got some undefined behavior . Read also this answer to have an idea of what that could mean.

If you wish an explanation, you need to dive into implementation specific details. Here it goes....

This carp.c file (very similar to yours, I renamed getChar to carp and included <stdio.h> )

 #include <stdio.h>
 char *carp() {
   char str[10] = "TEST!!!";
   return str;
 }
 int main(int argc, char**argv)
 {
   printf("STR is %s.\n", carp());
   return 0;
 }    

is compiled by gcc -O -fverbose-asm -S carp.c into a good warning

carp.c: In function 'carp':
carp.c:4:8: warning: function returns address of local variable [-Wreturn-local-addr]
      return str;
      ^

and into this assembler code (GCC 4.9.1 on Debian/Sid/x86-64)

    .text
.Ltext0:
        .globl  carp
        .type   carp, @function
carp:
.LFB11:
        .file 1 "carp.c"
        .loc 1 2 0
        .cfi_startproc
        .loc 1 5 0
        leaq    -16(%rsp), %rax #, tmp85
        ret
        .cfi_endproc
.LFE11:
        .size   carp, .-carp
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "STR is %s.\n"
        .text
        .globl  main
        .type   main, @function
main:
.LFB12:
        .loc 1 7 0
        .cfi_startproc
.LVL0:
        subq    $24, %rsp       #,
        .cfi_def_cfa_offset 32
        .loc 1 8 0
        movq    %rsp, %rsi      #,
.LVL1:
        movl    $.LC0, %edi     #,
.LVL2:
        movl    $0, %eax        #,
        call    printf  #
.LVL3:
        .loc 1 10 0
        movl    $0, %eax        #,
        addq    $24, %rsp       #,
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE12:
        .size   main, .-main

As you notice, the bad carp function is returning the stack pointer minus 16 bytes. And main would print what happens to be there. And what happens to be at that location probably depends upon a lot of factors (your environment environ(7) , the ASLR used for the stack, etc....). If you are interested in understanding what exactly is the memory (and address space) at entry into main , dive into execve(2) , ld.so(8) , your compiler's crt0 , your kernel's source code, your dynamic linker source code, your libc source code, the x86-64 ABI , etc.... My life is too short to take many hours to explain all of this.

BTW, notice that the initialization of local str to "TEST!!!" has been rightly optimized out by my compiler.

Read also signal(7) : your process can be terminated in many cases (I won't call that "Linux crashing" like you do), eg when dereferencing a pointer out of its address space in virtual memory (see also this ), executing a bad machine code, etc...

It didn't crash because you got lucky; since you have no way of knowing just how long this string that gets printed is, you have no idea what parts of memory it will venture into.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM