用gcc编译时如何增加默认栈的大小啊?

ganghust 2006-06-06 06:54:56
目前我的一个程序老师出现段错误,中间有很多递归操作,现在估计是默认栈太小了,希
望能够增加栈的大小,不知道编译选现如何设置,希望大侠指点:)
...全文
4226 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
HoBoss 2006-11-25
  • 打赏
  • 举报
回复
mark
lxzhou 2006-11-25
  • 打赏
  • 举报
回复
突然间才发现差距之大, 看来大学剩下来还有很多事要做。谢谢
koolfool 2006-11-25
  • 打赏
  • 举报
回复
我在FC3,gcc3.4.2环境下进行该实验,证明线程的栈确实有固定大小,也就是ulimit -a显示的那个值,在我的实验室环境下为10M字节
实验1:
#include <stdio.h>
#include <pthread.h>

int i = 0;

void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}

int main() {
pthread_t p;

pthread_create(&p, NULL, &test, NULL);
sleep(100);
}


并且可以使用如下代码修改这个线程栈的大小为16M:
实验2:
#include <stdio.h>
#include <pthread.h>

int i = 0;

void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}

int main() {
pthread_t p;
pthread_attr_t tattr;
void *stack;

pthread_attr_init(&tattr);

stack=malloc(16*1024*1024);
pthread_attr_setstack(&tattr,stack,16*1024*1024); //注意这个空间应该从堆中分配,如果从栈中分配,就会出现另一个问题,我们后面会提到
pthread_create(&p, &tattr, &test, NULL);
sleep(100);
}

但是如果用两个线程使用默认大小,来进行上面的实验,两个栈的总和并不是一个线程的二倍,并且这个总和也不是固定值
实验3:
#include <stdio.h>
#include <pthread.h>

int i = 0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

void *test(void * s) {
int buffer[1024];
pthread_mutex_lock(&mutex);
printf("i=%d\n", i);
i++;
pthread_mutex_unlock(&mutex);
test(s);
}

int main() {
pthread_t p1,p2;
pthread_create(&p1, NULL, &test, NULL);
pthread_create(&p2, NULL, test, NULL);
sleep(100);
}

如果不使用任何线程的话,那么一个进程的栈也不是理论上的2G,而是比一个线程的栈稍(ulimit -a 的值10M)大一些,并且这个栈的大小也不总是固定的
实验4:
#include <stdio.h>

int i=0;

void fun()
{
int buffer[1024];
printf("i=%d\n",i);
i++;
fun();
}

int main()
{
fun();
sleep(100);
}

如果pthread_attr_setstack设置的线程栈是从栈空间分配的话,如果线程栈的大小为10M的话,那么线程栈的大小也不是固定不变了而是和实验4的结果相同(类似?)
如果线程栈大小为11M的话,那么线程栈的大小也不是固定不变,但这个时候有可能在进程一开始的时候就发生段错误,即使是同一个可执行文件多次不同执行也会出现这种现象,说明这个栈的大小是和gcc的编译与链接无关的

实验5:
#include <stdio.h>
#include <pthread.h>

int i = 0;

void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}

int main() {
pthread_t p;
pthread_attr_t tattr;
char stack[11*1024*1024];

pthread_attr_init(&tattr);

pthread_attr_setstack(&tattr,&stack[0],11*1024*1024);
pthread_create(&p, &tattr, &test, NULL);
sleep(100);
}

结论:
1. 进程的栈大小是在进程执行的时刻才能指定的,即不是在编译的时刻决定,也不是链接的时刻决定,否则就不会有实验5的结果
2. 进程的栈大小是随机确定的至少比线程的栈要大,但是不到线程栈大小的2倍
3. 线程栈的大小是固定的,也就是ulimit -a显示的值
无知者无谓 2006-11-24
  • 打赏
  • 举报
回复
同意1楼
hyg2008 2006-11-24
  • 打赏
  • 举报
回复
mark
starstargao 2006-11-24
  • 打赏
  • 举报
回复
the size of linux kernel stack is 8K , users' is 8M
this is the data of rehat 9 default
overearth 2006-08-24
  • 打赏
  • 举报
回复
Visual C++可以在链接的指定,gcc 的用法我也一直在找..
nwcow 2006-08-24
  • 打赏
  • 举报
回复
ld用--stack reserved,commit
liu584 2006-08-24
  • 打赏
  • 举报
回复
关注
beepbug 2006-06-15
  • 打赏
  • 举报
回复
在IA-32(32位Intel芯片)里,进程的虚拟空间是4GB。其中包括进程头、正文段、数据段、栈空间,剩下的留作堆空间,用于动态分配。栈空间是在进程生成时,由系统一次性分配的,不太可能有2GB大。
栈空间有一个默认大小,可以在编译时,由某个链接开关(哪个忘了,LZ可以翻翻GCC资料)改变大小。因此,确切地说,是在链接时确定的。

--------------------------
我的BLOG:http://blog.csdn.net/beepbug/
x86 2006-06-07
  • 打赏
  • 举报
回复
把测试代码改成下面这样可以确定线程的栈确实有2M的限制:

#include <stdio.h>
#include <pthread.h>

int i = 0;

void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}

int main() {
pthread_t p;
pthread_create(&p, NULL, &test, NULL);
sleep(100);
}
x86 2006-06-07
  • 打赏
  • 举报
回复
线程的栈似乎有一定限制,这个可以做实验来确认一下。
x86 2006-06-07
  • 打赏
  • 举报
回复
首先你需要运行
ulimit -a
看一下stack是否被限制,如果是unlimited,那么栈的大小只受内存大小限制,当然还有一个2G的上限。至于是否能达到2G上限,答案是否定的,因为除了栈,程序还有别的地方会用到内存。不过linux在某种方式下可以用到最高64G的内存,不知道栈是否也可以突破2G的限制。

给你给小程序来测试栈的限制,
先用ulimit -s 1024设置stack限制为1024k,运行下面的程序会发现i=252的时候会段错误,此时栈大概用了252*(4k+x),差不多是1024k,其中的x是每次递归的开销,包括函数调用地址压栈,4k是每次递归的数组(局部变量)占用栈的大小。

如果栈的限制是unlimited,仔细看一下你的代码,也许是其他问题导致段错误,因为递归一般不会引起栈不够,除非你的程序逻辑有问题造成无限制递归。

#include <stdio.h>

int i = 0;

void test() {
int buffer[1024];
printf("i=%d\n", i);
i++;
test();
}

int main() {
test();
}
xiangding 2006-06-07
  • 打赏
  • 举报
回复
楼上的,在window中,栈的大小就是在编译中指定的,难道linux不一样吗?

liumangxiong(陈世奎): 栈可以达到2G? 错了吧,如果是一个线程里面?栈好像只有2M而已吧。
linaxing 2006-06-07
  • 打赏
  • 举报
回复
栈的大小不是编译时决定的,所以不能在编译时增加它的大小。
可以用setrlimit()来增加栈的大小。
ganghust 2006-06-07
  • 打赏
  • 举报
回复
谢谢了。我这个程序是从x86移植到powerpc上的,使用List操作的地方老有问题。
linaxing 2006-06-07
  • 打赏
  • 举报
回复
to: xiangding(一蓑烟雨任平生!)
让你给说中了,linux下确实不一样,linux下的可执行文件不会像windows下的一样将栈的大小记录到可执行文件中,所以你不能在gcc中指定栈的大小!
NNBWOLF 2006-06-07
  • 打赏
  • 举报
回复
学习
zengwh 2006-06-07
  • 打赏
  • 举报
回复
gdb ***
bt
  • 打赏
  • 举报
回复
一般情况下是不会出现栈太小的,因为用户空间中栈可以有2G多的空间。仔细检查一下指针的使用吧,是不是使用了未初始化的指针了?最直接的办法,就是用GDB跟踪到出错的地方,那就知道究竟是什么出错了。

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧