【发布时间】:2023-03-06 16:27:01
【问题描述】:
我已将 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 似乎相当多。
在调用入口例程之前,线程的堆栈中放置了哪些信息?
谢谢 菲利普
【问题讨论】:
-
我在 MacOS 上使用 gcc 编译和运行程序没有问题。
-
我唯一能想到的是你可以检查 pthread_attr_setstacksize(...) == 0 的返回值。如果你尝试,手册页说它返回 -1 并将 errno 设置为 EINVAL将堆栈大小设置为高于某些系统强加的限制。不过,这似乎不太可能。
-
看看
ulimit -s的输出 - 你可能没有得到每个线程的全部 16K。 -
@Kevin 很高兴知道您可以在 MacOS 上运行该程序。也许你可以尝试增加数组的大小,看看你能走多远?
-
@Kevin pthread_attr_setstacksize 函数返回 0。此外,我还有 pthread_attr_getstacksize 的堆栈大小请求。这似乎很好。