1

代码是

/* test_etext.c */

#include <unistd.h>
#include <stdio.h>

extern char etext, edata, end;

int
main(int argc, char *argv[])
{
    pid_t pid, ppid;

    pid = getpid();
    ppid = getppid();

    printf("%ld\t%ld\t%ld\n", &etext, &edata-&etext, &end-&edata);

    return 0;
}

然后像这样编译运行

gcc -o test_etext test_etext.c

./test_etext
4196125 2099507 8

size ./test_etext
text       data     bss     dec     hex filename
1532        592       8    2132     854 ./test_etext

问题是为什么“&edata-&etext”和“data”之间的段数据不同?

4

1 回答 1

1

他们当然不一样!你甚至读过手册页man 3 etext吗?

  • etext是文本(代码)末尾之后的第一个地址,
  • edata是初始化数据末尾之后的第一个地址,并且
  • end是未初始化数据 (bss) 末尾之后的第一个地址

由于地址空间随机化,您不应该假设上述内存中的布局。因此,它们的差异无法传达可靠的信息

要计算文本、初始化数据和未初始化数据的各自大小,您需要先找到相同的初始地址(并从相应的结束地址中减去)。

由于您标记了您的问题 Linux,我个人只是通过阅读/proc/self/statm伪文件来查询内核的意见。如果您需要更详细的信息(例如动态加载库的详细信息),或者与size命令输出匹配的信息,请读取/proc/self/smaps/proc/self/maps伪文件。这些都在 中详细描述man 5 proc

对于可执行的 ELF 文件——例如,类似于工作方式sizeobjdump工作方式——至少使用现有的实用程序或现有的库。

于 2013-05-02T02:36:35.863 回答