Reputation: 33
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?
Upvotes: 1
Views: 111
Reputation: 1
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), e.g. when dereferencing a pointer out of its address space in virtual memory (see also this), executing a bad machine code, etc...
Upvotes: 5
Reputation: 49803
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.
Upvotes: 2