我已将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, 0, 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的损失似乎非常多。
在调用入口例程之前,线程的堆栈上放了什么信息?
由于 菲利普
答案 0 :(得分:0)
在对glibc nptl源代码进行一些调查之后,我得出结论:在堆栈的底部放置了拥有堆栈的线程的pthread-struct,并且可能还有一些其他变量,具体取决于glibc-configuration。他们一起使用大约3K。堆栈的顶部填充了一个保护页面,通常是4K大。因此,已经使用了大约7-8K。我有点惊讶,至少保护页面的内存没有单独分配。在我的头脑中,我想要记住,情况确实如此,但事实并非如此。