C/C++数据段和堆栈大小是什么?

6

我读到说这取决于编译器和操作系统架构。在Linux系统中使用GCC作为编译器,如何找出数据段和堆栈的最大大小?


1
我会先查看GCC文档。 - Angew is no longer proud of SO
告诉你的链接器打印一个映射文件。该映射文件将列出所有段及其大小。没有标准告诉链接器或编译器如何生成映射文件。您需要查阅工具的文档。 - Thomas Matthews
数据段最大大小,不确定是否有最大大小。如果有的话也没有太多意义。最大堆栈大小:已经回答 - user4581301
3个回答

6

让我和你一起尝试:创建名为“test.c”的文件,内容如下:

int main (void) { return 0; }

现在进行编译,指定最大堆栈大小(仅为了在地图文件中轻松查找此数字并确定符号名称,引用它)。
gcc test.c -o test.x -Wl,--stack=0x20000 -Wl,-Map=output.map

确定数据大小很简单:
size -A -d test.x

你将得到类似于这样的东西:
section           size         addr
.text             1880   4299165696
.data              104   4299169792
...

此外,"objdump -h test.x" 也可以正常工作,但结果不够详细。

这里有更多的部分(不仅仅是代码和数据),但这里没有堆栈信息。为什么?因为堆栈大小不是ELF节,它仅在加载并执行您的程序后才会被保留。您应该从文件中的某个(平台相关的)符号中读取它,就像这样:

$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__

当编译时指定大小为0x20000,因此大小为0x20000并不奇怪。

我通过查看生成的output.map文件来确定符号名称。建议您也从这里开始查看。

当您有一些未知的a.out文件时,只需重复以下步骤:

size -A -d a.out
nm a.out | grep __size_of_stack_reserve__

替换平台相关的符号,使用上面描述实验中确定的符号。

4

段是组织可执行文件所需内容的一种方法。

数据段通常用于可执行文件使用的任何数据(不涉及外部输入)。某些数据段可能包含字符串文字或数字常量。

许多可执行文件使用堆栈来存储函数局部变量、语句块局部变量、返回地址和函数参数。堆栈不是C或C++语言所必需的;它只是一个方便的数据结构。

堆栈大小可以是分配给堆栈的容量,也可以是驻留在堆栈上的元素数量,或者是堆栈占用的内存量。

许多平台都有默认的堆栈大小。由于平台的差异,您需要阅读工具文档以了解如何设置堆栈大小以及默认容量是多少。


1
如何使用GCC编译器在Linux系统上查找数据段和堆栈最大大小?这些限制可以作为getrlimitRLIMIT_DATARLIMIT_STACK资源限制来读取。在命令行中,您可以使用ulimit命令查找系统的这些限制。
$ ulimit -s # stack
8515
$ ulimit -d # data
unlimited

您可以通过修改limits.conf来更改系统限制。

更多信息请参见man pthread_create:

在Linux / x86-32上,新线程的默认堆栈大小为2 MB。在NPTL线程实现下,如果程序启动时的RLIMIT_STACK软资源限制除了“无限”以外还有其他任何值,则它决定了新线程的默认堆栈大小。使用pthread_attr_setstacksize(3),可以在用于创建线程的attr参数中显式设置堆栈大小属性,以获得与默认值不同的堆栈大小。

并且在man ld中:

--stack reserve

--stack reserve,commit

指定要保留(和可选提交)用作此程序堆栈的内存字节数。默认值为2MB保留,4K提交。[此选项仅适用于链接器针对i386 PE目标端口]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接