使用/ proc / pid / stat的错误条目?

时间:2015-04-21 18:49:55

标签: c linux memory-management memory-mapping

我编写了一个简单的C程序,包含一些全局变量和静态变量。一些代码和输出可以在下面显示。

示例源代码:

#include <stdio.h>

int g1, g2;

int main(){

     printf("g1:%p g2:%p\n", &g1, &g2);

     return 0;
}

输出:

g1:0x6061b0 g2:0x6061c0

此类变量属于数据段。它们可以在初始化的小节中,也可以在未初始化的(bss)小节中。我打印它们的地址以检查它们在内存中的位置,然后我将这些值与start_data伪文件的end_data/proc/<pid>/stat条目的值进行比较。我的变量属于该区域。

限制/ proc / pid / stat给我:

start_data: 604e10
end_data:   605180

来自documentation

  

45)start_data %lu(自Linux 3.3起)                           地址上面的程序初始化和                           放置未初始化(BSS)数据。

     

(46)end_data %lu(自Linux 3.3起)                           地址低于哪个程序初始化和                           放置未初始化(BSS)数据。

我已设法使用data segment生成的map file获取linker的正确区域,但是通过使用proc界面,它会更清晰(更容易,更快,..)。

我使用链接器中的mapfile找到了正确的限制:

start: 605168
end:   606290

我正在使用Ubuntu Server x64,Linux 3.13。

统计信息的完整输出:

29505 (myexec) R 29504 29504 1438 34822 29504 24640 52 0 0 0 0 0 0 0 20 0 1 0 55253161 4308992 24 18446744073709551615 4194304 4210644 140737488347232 140737488337560 140737348896784 0 0 0 0 0 0 0 17 0 0 0 0 0 0 6311440 6312320 6320128 140737488347816 140737488347831 140737488347831 140737488351209 0

map_files的输出:

total 0
lr-------- 1 root root 64 Apr 21 22:32 400000-41a000 -> /bin/ls
lr-------- 1 root root 64 Apr 21 22:32 619000-61a000 -> /bin/ls
lr-------- 1 root root 64 Apr 21 22:32 61a000-61b000 -> /bin/ls
lr-------- 1 root root 64 Apr 21 22:32 7ffff649e000-7ffff64a9000 -> /lib/x86_64-linux-gnu/libnss_files-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff64a9000-7ffff66a8000 -> /lib/x86_64-linux-gnu/libnss_files-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff66a8000-7ffff66a9000 -> /lib/x86_64-linux-gnu/libnss_files-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff66a9000-7ffff66aa000 -> /lib/x86_64-linux-gnu/libnss_files-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff66aa000-7ffff66b5000 -> /lib/x86_64-linux-gnu/libnss_nis-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff66b5000-7ffff68b4000 -> /lib/x86_64-linux-gnu/libnss_nis-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff68b4000-7ffff68b5000 -> /lib/x86_64-linux-gnu/libnss_nis-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff68b5000-7ffff68b6000 -> /lib/x86_64-linux-gnu/libnss_nis-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff68b6000-7ffff68cd000 -> /lib/x86_64-linux-gnu/libnsl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff68cd000-7ffff6acc000 -> /lib/x86_64-linux-gnu/libnsl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6acc000-7ffff6acd000 -> /lib/x86_64-linux-gnu/libnsl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6acd000-7ffff6ace000 -> /lib/x86_64-linux-gnu/libnsl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6ad0000-7ffff6ad9000 -> /lib/x86_64-linux-gnu/libnss_compat-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6ad9000-7ffff6cd8000 -> /lib/x86_64-linux-gnu/libnss_compat-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6cd8000-7ffff6cd9000 -> /lib/x86_64-linux-gnu/libnss_compat-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6cd9000-7ffff6cda000 -> /lib/x86_64-linux-gnu/libnss_compat-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff6cda000-7ffff6fa3000 -> /usr/lib/locale/locale-archive
lr-------- 1 root root 64 Apr 21 22:32 7ffff6fa3000-7ffff6fa7000 -> /lib/x86_64-linux-gnu/libattr.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff6fa7000-7ffff71a6000 -> /lib/x86_64-linux-gnu/libattr.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff71a6000-7ffff71a7000 -> /lib/x86_64-linux-gnu/libattr.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff71a7000-7ffff71a8000 -> /lib/x86_64-linux-gnu/libattr.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff71a8000-7ffff71ab000 -> /lib/x86_64-linux-gnu/libdl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff71ab000-7ffff73aa000 -> /lib/x86_64-linux-gnu/libdl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff73aa000-7ffff73ab000 -> /lib/x86_64-linux-gnu/libdl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff73ab000-7ffff73ac000 -> /lib/x86_64-linux-gnu/libdl-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff73ac000-7ffff73e9000 -> /lib/x86_64-linux-gnu/libpcre.so.3.13.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff73e9000-7ffff75e8000 -> /lib/x86_64-linux-gnu/libpcre.so.3.13.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff75e8000-7ffff75e9000 -> /lib/x86_64-linux-gnu/libpcre.so.3.13.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff75e9000-7ffff75ea000 -> /lib/x86_64-linux-gnu/libpcre.so.3.13.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff75ea000-7ffff77a5000 -> /lib/x86_64-linux-gnu/libc-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff77a5000-7ffff79a4000 -> /lib/x86_64-linux-gnu/libc-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff79a4000-7ffff79a8000 -> /lib/x86_64-linux-gnu/libc-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff79a8000-7ffff79aa000 -> /lib/x86_64-linux-gnu/libc-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff79af000-7ffff79b6000 -> /lib/x86_64-linux-gnu/libacl.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff79b6000-7ffff7bb5000 -> /lib/x86_64-linux-gnu/libacl.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff7bb5000-7ffff7bb6000 -> /lib/x86_64-linux-gnu/libacl.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff7bb6000-7ffff7bb7000 -> /lib/x86_64-linux-gnu/libacl.so.1.1.0
lr-------- 1 root root 64 Apr 21 22:32 7ffff7bb7000-7ffff7bd7000 -> /lib/x86_64-linux-gnu/libselinux.so.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff7bd7000-7ffff7dd6000 -> /lib/x86_64-linux-gnu/libselinux.so.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff7dd6000-7ffff7dd7000 -> /lib/x86_64-linux-gnu/libselinux.so.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff7dd7000-7ffff7dd8000 -> /lib/x86_64-linux-gnu/libselinux.so.1
lr-------- 1 root root 64 Apr 21 22:32 7ffff7dda000-7ffff7dfd000 -> /lib/x86_64-linux-gnu/ld-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff7ffc000-7ffff7ffd000 -> /lib/x86_64-linux-gnu/ld-2.19.so
lr-------- 1 root root 64 Apr 21 22:32 7ffff7ffd000-7ffff7ffe000 -> /lib/x86_64-linux-gnu/ld-2.19.so

有什么想法? 欢呼声。

1 个答案:

答案 0 :(得分:3)

似乎是(或不正确的文档)。

ELF使用一个小技巧来指定BSS(我切掉前导零):

$ objdump -x ./a.out

LOAD off    0x00000e00 vaddr 0x00600e00 paddr 0x00600e00 align 2**21
     filesz 0x00000258 memsz 0x00000268 flags rw-

对于那个PT_LOAD:

vaddr = 0x00600e00
vaddr + filesz = 0x00601058
vaddr + memsz = 0x00601068

所以字节[0x00600e00; 0x00601058]从文件加载到内存中,而最后的0x10字节也应该存在于内存中,但不能从ELF文件中加载 - 它们归零,因为它是BSS。您也可以使用objdump检查:

25 .bss    00000010  00601058  00601058  00001058  2**2
           ^ size    ^ base address

但是,在ELF的binfmt加载器中,只有vaddr + filesz被计为end_data(请参阅fs/binfmt_elf.c):

k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;

if (k > elf_bss)
    elf_bss = k;
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
    end_code = k;
if (end_data < k)
    end_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
if (k > elf_brk)
    elf_brk = k;

所以:

  • end_data指向从文件
  • 加载的最后一个字节
  • elf_bss指向BSS的第一个字节(未公开,在内部使用)
  • elf_brk指向BSS的最后一个字节(未公开,在内部使用)

您可以查看/proc/PID/maps - 它应该显示更可靠的结果。

P.S。似乎内核文档已经被随机的陌生人改变了:https://lkml.org/lkml/2011/12/6/604