[英]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);
}
我知道不應返回堆棧中的臨時變量。
實際上,它將輸出一個不確定的字符串。
除了NULL-Pointer-Reference,Linux何時會崩潰?
您有一些不確定的行為 。 另請閱讀此答案 ,以了解可能的含義。
如果您希望得到解釋,則需要深入研究實現特定的細節。 來了...
這個carp.c
文件(與您的文件非常相似,我將getChar
重getChar
為carp
並包含了<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;
}
由gcc -O -fverbose-asm -S carp.c
成一個很好的警告
carp.c: In function 'carp':
carp.c:4:8: warning: function returns address of local variable [-Wreturn-local-addr]
return str;
^
並進入此匯編代碼(Debian / Sid / x86-64上的GCC 4.9.1)
.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
如您所見,不良的carp
函數將返回減去16個字節的堆棧指針。 而main
會打印碰巧存在的內容。 而且該位置的情況可能取決於許多因素(您的環境environ(7) ,用於堆棧的ASLR等...)。 如果您想了解進入main
確切內存(和地址空間),請深入了解execve(2) , ld.so(8) ,編譯器的crt0 ,內核的源代碼,動態鏈接器源代碼,您的libc
源代碼, x86-64 ABI等。。。我的生活太短,無法花很多時間來解釋所有這些。
順便說一句,請注意將本地str
初始化為"TEST!!!"
已由我的編譯器正確 優化 。
閱讀也是信號(7) :你的過程可以在很多情況下(我不會稱之為“Linux的崩潰”像你這樣)終止,取消引用指針,例如當出其地址空間中的虛擬內存 (又見本 )執行錯誤的機器代碼,等等。
它並沒有因為幸運而崩潰。 由於您無法知道要打印的字符串的長度,因此您不知道它將進入哪部分內存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.