问题描述
|
我已将Linux中pthread的堆栈大小设置为16 KB。如果然后将一个大于8 KB的数组压入堆栈,则应用程序会因分段错误而停止。在我看来,我正在尝试访问堆栈底部下方的内存,这可能是未映射的内存,因此是段错误。
这是示例代码:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
void *start_routine(void *arg)
{
size_t size = 9*1024;
unsigned char arr[size];
memset(arr,size);
}
int main()
{
int err;
pthread_attr_t threadAttr;
size_t stacksize;
void *stackAddr;
pthread_t thread;
pthread_attr_init(&threadAttr);
pthread_attr_setstacksize(&threadAttr,16*1024);
pthread_attr_getstacksize(&threadAttr,&stacksize);
printf(\"stacksize: %d\\n\",stacksize);
pthread_create(&thread,&threadAttr,start_routine,NULL );
pthread_join(thread,NULL);
return 0;
}
我松散了大约8 KB的堆栈,这似乎很奇怪。我也尝试使用更大的堆栈大小。它似乎以某种方式改变了我可以使用的堆栈数量。
我知道对于当今的系统(某些嵌入式系统除外),这几个字节并不是很重要,但是我很好奇为什么我不能使用大部分已定义的堆栈。我不希望我可以使用整个堆栈,但是丢失大约8 KB似乎是很多的。
在调用入口例程之前,在线程的堆栈上放置了哪些信息?
谢谢
菲利普
解决方法
在对glibc nptl源代码进行了一些研究之后,我得出的结论是,在堆栈的底部放置了拥有堆栈的线程的pthread-struct,并可能根据glibc的配置提供了一些其他变量。他们一起使用大约3K。堆栈的顶部装有保护页,通常为4K大。因此大约已经使用了7-8K。至少对于保护页面的内存没有单独分配,我感到有些惊讶。我想着要记住那是事实,但事实并非如此。