程序
#include<stdio.h>
int a=10;
void main()
{
int i=0;
printf("global = %p, local = %p\n",&a,&i);
main();
}
输出
mohanraj@ltsp63:~/Advanced_Unix/Chapter7$ ./a.out
global = 0x804a014, local = 0xbfff983c
global = 0x804a014, local = 0xbfff980c
.
.
.
global = 0x804a014, local = 0xbf7fac9c
global = 0x804a014, local = 0xbf7fac6c
global = 0x804a014, local = 0xbf7fac3c
Segmentation fault (core dumped)
mohanraj@ltsp63:~/Advanced_Unix/Chapter7$
上述程序出现分段错误。因为主函数调用了自身,导致递归。以下是C程序的内存分配。
内存分配
__________________ __________________
| | | |
| stack | | Main |
| ↓ | |----------------|
------------------ | Main |
| | |----------------|
| <Un Allocated| | Main |
| space> | |----------------|
------------------ | Main |
| | |----------------|
| ↑ | | Main |
| Heap | |----------------|
| | | Main |
| | |----------------|
__________________ |////////////////| ---> Collision occurs. So, Segmentation fault Occurs.
| | |________________|
| data | | data |
__________________ |________________|
| text | | text |
__________________ |________________|
Figure(a) Figure(b)
所以,我期望像图(b)中展示的那样,主函数被递归调用。如果它到达了数据段,就会发生碰撞。 如果发生了碰撞,就没有更多的空间来分配给主函数。因此,它会得到分段错误。因此,使用上面的程序进行实验。 在该程序中,全局变量'a'的地址为"0x804a014"。每次调用主函数时,本地变量"i"都会被声明。所以, 我期望,在分段错误之前,'i'的地址接近于'a'的地址。但是,这两个地址非常不同。那么这里发生了什么。
为什么在分段错误发生时,'a'和'i'的地址不在同一范围内?那么,如何交叉检查主函数是否达到了堆栈大小并被溢出?
/proc/pid/maps
- 其中还有其他东西,比如库。此外,堆栈大小实际上是有限制的(ulimit)。 - Anya Shenanigans