- 论坛徽章:
- 0
|
如果只说理解大概原理来说,基本上是对的。 但实际情况不是这样,实际是这样的:
1. 首先Linux内核为了防止参数不定的情况? stack的起始地址是0xc000000-32*4096-??.
2. Linux内核使用Linux-gate作为系统调用入口,这个入口在固定位置,需要占用1页虚址
3. 还有动态库的情况,基本上应用程序使用动态库的占多数,所以应用程序加载的虚址一般从0x80xxxxxx开始,即text的起始地址是0x80xxxxxx
4. 应用程序运行中可能需要使用dlopen()打开动态库,其中的text+data+bss这又会占用你认为的heap+stack的空间
5. 最后,假设即使一个应用程序有超过1G的heap空间可以使用,如果你的系统使用512M内存+512M交换分区的组合,默认情况下最多只能malloc() 512/2+512(M)内存,如果我没有记错的话,这是内核的vm overcommit机制,我记得以前我写过一个这样的文档。可以通过/proc/sys/vm/overcommit_memory和/proc/sys/vm/overcommit_ratio调节。设想一下,如果你真的需要这么多内存来运行这个应用程序,即使分配到了1G的虚存,也不可能有这么多物理内存+交换分区使用。
下面是一个我机器上的例子:
[xiaozhaoz@xiaozhaoz_linux x86]$ cat /proc/version
Linux version 2.6.18 (xiaozhaoz@xiaozhaoz_linux) (gcc version 4.0.0 20050519 (Red Hat 4.0.0- ) #5 PREEMPT Thu Sep 21 09:26:16 CST 2006
---------------------------------------------------------------------
[xiaozhaoz@xiaozhaoz_linux x86]$ readelf -l /bin/bash
Elf file type is EXEC (Executable file)
Entry point 0x805b600
There are 8 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08047034 0x08047034 0x00100 0x00100 R E 0x4
INTERP 0x000134 0x08047134 0x08047134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08047000 0x08047000 0xa1694 0xa1694 R E 0x1000
LOAD 0x0a1694 0x080e9694 0x080e9694 0x057e8 0x0a108 RW 0x1000
DYNAMIC 0x0a16a8 0x080e96a8 0x080e96a8 0x000d8 0x000d8 RW 0x4
NOTE 0x000148 0x08047148 0x08047148 0x00020 0x00020 R 0x4
GNU_EH_FRAME 0x0925d8 0x080d95d8 0x080d95d8 0x034cc 0x034cc R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .gnu.liblist .gnu.conflict .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .dynbss .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
---------------------------------------------------------------------
[xiaozhaoz@xiaozhaoz_linux x86]$ ldd /bin/bash
linux-gate.so.1 => (0xffffe000)
libtermcap.so.2 => /lib/libtermcap.so.2 (0x00807000)
libdl.so.2 => /lib/libdl.so.2 (0x0067a000)
libc.so.6 => /lib/libc.so.6 (0x00528000)
/lib/ld-linux.so.2 (0x0050a000)
---------------------------------------------------------------------
[xiaozhaoz@xiaozhaoz_linux x86]$ cat /proc/2599/maps
0050a000-00524000 r-xp 00000000 fe:00 2393276 /lib/ld-2.3.5.so
00524000-00525000 r--p 00019000 fe:00 2393276 /lib/ld-2.3.5.so
00525000-00526000 rw-p 0001a000 fe:00 2393276 /lib/ld-2.3.5.so
00528000-0064c000 r-xp 00000000 fe:00 2393277 /lib/libc-2.3.5.so
0064c000-0064e000 r--p 00124000 fe:00 2393277 /lib/libc-2.3.5.so
0064e000-00650000 rw-p 00126000 fe:00 2393277 /lib/libc-2.3.5.so
00650000-00652000 rw-p 00650000 00:00 0
0067a000-0067c000 r-xp 00000000 fe:00 2393279 /lib/libdl-2.3.5.so
0067c000-0067d000 r--p 00001000 fe:00 2393279 /lib/libdl-2.3.5.so
0067d000-0067e000 rw-p 00002000 fe:00 2393279 /lib/libdl-2.3.5.so
00807000-0080a000 r-xp 00000000 fe:00 2392133 /lib/libtermcap.so.2.0.8
0080a000-0080b000 rw-p 00002000 fe:00 2392133 /lib/libtermcap.so.2.0.8
08047000-080e9000 r-xp 00000000 fe:00 1638482 /bin/bash
080e9000-080ef000 rw-p 000a1000 fe:00 1638482 /bin/bash
080ef000-08136000 rw-p 080ef000 00:00 0 [heap]
b7dc2000-b7dcb000 r-xp 00000000 fe:00 2392117 /lib/libnss_files-2.3.5.so
b7dcb000-b7dcc000 r--p 00008000 fe:00 2392117 /lib/libnss_files-2.3.5.so
b7dcc000-b7dcd000 rw-p 00009000 fe:00 2392117 CE褡约旱目占渲小?inux-gate.so是一个不存在的文件,是内核的一个物理内存页,可以使用dd 读取出来,反汇编看看就知道了。 |
|