我试图了解在具有gcc的Linux x86_64系统上,堆栈分配和对齐方式如何与pthread一起使用,以及系统在堆栈上存储哪些数据。我知道您可以使用pthread_attr_setstack
配置堆栈内存。我已经在执行以下操作的测试程序中完成了此操作:
1)递归调用自身并更新在堆栈上分配的未初始化数组
2)打印出第一个数组元素,最后一个元素和rsp的值
由此,我可以观察到rsp如何递增(在我的测试程序中,我注意到编译器内联了一些递归调用)。我还能够看到添加TLS内存(带有__thread变量)会导致rsp的第一个值降低。因此,似乎TLS变量分配在堆栈的顶部。
但是,我不确定还有什么。在我看来,堆栈的第一页是以某种方式为系统保留的,因为我分配的堆栈变量都没有以该区域结尾。即使我不使用任何__thread变量,我实例化的变量似乎也不会分配在第一页中(我将堆栈内存设置为页面对齐)。
所以我的问题是:除了TLS数据和堆栈变量外,pthread堆栈上还有什么(如果有的话)?
最佳答案
在Linux NPTL上:
堆栈的最顶部包含TCB。这也称为struct pthread
或pthread_t
。由于所有怪异的glibc系统特定的定义,这有点毛茸茸,但基本上它包含以下内容:
pthread_cleanup
并堆栈展开信息pthread_setspecific
使用的一定数量的TLS插槽-如果超过此数量,其余的插槽将分配在堆pthread_join
的跟踪信息在新线程实际开始运行之前,这主要是在
pthread_create
中初始化的(如果您正在eglibc源代码中,则是__pthread_create_2_1
中的nptl/pthread_create.c
)。TCB下方是静态分配的
__thread
变量-或至少链接程序在启动时可以识别的变量。动态链接器在链接器映射中初始化l_tls_offset
字段,以告诉NPTL代码保留多少空间。请注意,程序启动后加载的库将不属于此部分-有关详细信息,请参见 __thread
ABI spec。__thread
变量下面是堆栈。堆栈的顶部是start_thread()
代码,因此它仍然是实际执行用户代码之前的一种方式(但不要过多)。关于linux - 哪些系统数据存储在堆栈中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8482079/