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);
}
Run Code Online (Sandbox Code Playgroud)
我知道堆栈中的临时变量不应该被返回.
实际上它会输出一个未定的字符串.
除了NULL-Pointer-Reference之外什么时候Linux崩溃?
如果您想要解释,您需要深入了解具体实施细节.这里......
这个carp.c文件(你的差不多,我改名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;
}
Run Code Online (Sandbox Code Playgroud)
编译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;
^
Run Code Online (Sandbox Code Playgroud)
并加入此汇编代码(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
Run Code Online (Sandbox Code Playgroud)
正如您所注意到的,错误的carp函数是将堆栈指针返回减去16个字节.而main将打印会发生什么在那里.而在该位置发生的事情可能取决于很多因素(您的环境环境(7),用于堆栈的ASLR等等).如果您有兴趣了解究竟是什么在进入存储(和地址空间)main,潜入的execve(2) ,ld.so(8) ,你的编译器的信息crt0,你的内核源代码,您的动态链接程序的源代码,您libc源代码,x86-64 ABI等....我的生命太短暂,不需要花费很多时间来解释所有这些.
顺便说一句,请注意当地的初始化str到"TEST!!!"已经正确地 优化,通过我的编译器了.
同时读取信号(7):在许多情况下你的进程可以终止(我不会像你那样称之为"Linux崩溃"),例如当从虚拟内存中的地址空间中取消引用指针时(参见本节),执行错误的机器代码等...
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |