免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 18507 | 回复: 59
打印 上一主题 下一主题

linux虚拟地址空间疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-15 14:48 |只看该作者 |倒序浏览
读CSAPP第10章的疑惑
1,Linux每个进程有个虚拟地址空间,它的虚拟页面初始化时,其内容会在内核维护的专门的交换文件(swap file)间换来换去,交换文件也叫交换空间或交换区域
    请问这个交换文件跟设置的某个作为交换分区的磁盘分区有什么联系?
    “任何时候,交换空间都限制着当前运行的进程能够分配的虚拟页面的总数”,这句话怎么理解了?
2,在Linux进程的虚拟空间中,共享库分配在0x40000000开始处的区域,进程的堆区在它的下面,堆会向上长,内核的brk指针标识堆的界限,当brk长到0x40000000时系统怎样处理?
    还能继续长吗?
3,在ulimit命令中,设置
    ulimit -v unlimited
      virtual memory          (kbytes, -v) unlimited
    这个virtual memory是什么意思了?设为unlimited是什么含义了?
4,ulimit中core dump打开的情况下,某个用户进程崩溃了,进行存储转储,它存储进程的哪些信息?

谢谢先!

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
2 [报告]
发表于 2007-09-15 17:30 |只看该作者
1) 交换文件实际上不是一个,而是是一串交换文件,表示为swap_info_struct结构的单向链.每个swap_info_struct可以表示一个块设备文件,也可以表示一个普通文件.
串中每个交换文件可以用sys_swapon和sys_swapoff来开启或者关闭,控制kernel是否使用这个交换文件
作为交换分区的磁盘分区,对应着串中一个交换文件,而且在系统启动时,这个交换文件默认为开启.

交换文件的串中,各个交换文件的大小累加起来,既虚拟内存总的大小.
对于进程的页面来说,每个页面要么影射到进程自己打开的文件,要么影射到交换文件.没有不影射到任何文件的page(匿名页),当进程里出现了匿名页的时候,kswapd进程马上会把匿名页影射到交换文件.因此,所有进程的所有page中,除开影射到进程自己打开的文件里的page,其他page的数量,不得超过交换文件串里所有交换文件的容量之和.

2)共享库偏爱(kernel叫bias,大概指偏爱)从1G开始,但不是绝对.
   brk的优先级最低,brk段不能覆盖掉文件影射段或匿名影射段,与其他段发生冲突时,无法brk.
  但是相反,sys_mmap2时,如果指定MAP_FIXED,可以覆盖掉brk段

3)ulimit是什么?

4)core dump时,转储的内容依赖于具体的文件格式,每种文件格式都有自己的core_dump函数.

论坛徽章:
0
3 [报告]
发表于 2007-09-15 18:57 |只看该作者
ulimit是地址空间大小,那几个系统调用都会使用到这个值

论坛徽章:
0
4 [报告]
发表于 2007-09-15 19:02 |只看该作者
(抱拳),多谢塑料袋兄的回复
1,有头绪了
2,似懂非懂了
3,是用户空间使用的设置内核参数的一个工具,你尝试一下ulimit -a,看看输出,依你内核水平马上就知晓输出的含义了
4,对于ELF格式的文件转储哪些内容了?

论坛徽章:
0
5 [报告]
发表于 2007-09-15 19:44 |只看该作者
sys_mmap2时,如果指定MAP_FIXED,可以覆盖掉brk段
不是失败吗?

2.它从进程的地址空间数据结构里找,发现如果这么做有覆盖了就失败了,一直以为mmap也是这么做的

论坛徽章:
0
6 [报告]
发表于 2007-09-15 19:45 |只看该作者
实验的疑惑:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    printf("PID :%d\n",getpid());
    void *ptr =sbrk(0);
    printf("ptr: %p\n",ptr);
    ptr = malloc(0x1000000UL);
    printf("ptr: %p\n",ptr);
    ptr = malloc(0x1000000UL);
    printf("ptr: %p\n",ptr);
    ptr = sbrk(0);
    printf("ptr: %p\n",ptr);
    sleep(100);
    return 0;
}
# uname -a
Linux lfslivecd 2.6.22.5 #1 SMP Fri Aug 31 15:46:21 GMT 2007 i686 pentium4 i386 GNU/Linux
# gcc -v
使用内建 specs。
目标:i486-pc-linux-gnu
配置为:../gcc-4.1.2/configure --prefix=/usr --libexecdir=/usr/lib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++ --enable-static --disable-multilib
线程模型:posix
gcc 版本 4.1.2
# gcc -o test test.c -Wall
test.c: 在函数 ‘main’ 中:
test.c:11: 警告:隐式声明函数 ‘malloc’
test.c:11: 警告:隐式声明与内建函数 ‘malloc’ 不兼容

# ./test &
[1] 1775
lfslivecd:root | 2007年09月15日 星期六 19时30分28秒 | /mnt/lfs/sources
# PID: 1775
ptr: 0x804a000
ptr: 0xb6dd9008
ptr: 0xb5dd8008
ptr: 0x804a000

lfslivecd:root | 2007年09月15日 星期六 19时30分29秒 | /mnt/lfs/sources
# cat /proc/1775/maps
08048000-08049000 r-xp 00000000 08:02 780348     /mnt/lfs/sources/test
08049000-0804a000 rw-p 00000000 08:02 780348     /mnt/lfs/sources/test
b5dd8000-b7ddb000 rw-p b5dd8000 00:00 0
b7ddb000-b7f00000 r-xp 00000000 fe:00 81937      /lib/libc-2.5.1.so
b7f00000-b7f02000 r--p 00125000 fe:00 81937      /lib/libc-2.5.1.so
b7f02000-b7f03000 rw-p 00127000 fe:00 81937      /lib/libc-2.5.1.so
b7f03000-b7f07000 rw-p b7f03000 00:00 0
b7f0f000-b7f10000 rw-p b7f0f000 00:00 0
b7f10000-b7f11000 r-xp b7f10000 00:00 0          [vdso]
b7f11000-b7f2b000 r-xp 00000000 fe:00 81960      /lib/ld-2.5.1.so
b7f2b000-b7f2c000 r--p 00019000 fe:00 81960      /lib/ld-2.5.1.so
b7f2c000-b7f2d000 rw-p 0001a000 fe:00 81960      /lib/ld-2.5.1.so
bfc03000-bfc19000 rw-p bfc03000 00:00 0          [stack]


从这里看来,共享库是放在栈的下面,再接着作为堆,并且这个堆是向小地址方向下扩展的
晕了,CSAPP讲的Linux虚拟地址空间的知识有点过时了,不知道其他版本的编译器和链接器的情况是怎样的

修改程序,malloc一次不分配16M,只分配4K,是如下情况,
# ./test &
[1] 1783
PID: 1783
ptr: 0x804a000
ptr: 0x804a008
ptr: 0x804b010
ptr: 0x806c000
lfslivecd:root | 2007年09月15日 星期六 19时38分22秒 | /mnt/lfs/sources
# cat /proc/1783/maps
08048000-08049000 r-xp 00000000 08:02 780348     /mnt/lfs/sources/test
08049000-0804a000 rw-p 00000000 08:02 780348     /mnt/lfs/sources/test
0804a000-0806c000 rw-p 0804a000 00:00 0          [heap]
b7dbe000-b7dbf000 rw-p b7dbe000 00:00 0
b7dbf000-b7ee4000 r-xp 00000000 fe:00 81937      /lib/libc-2.5.1.so
b7ee4000-b7ee6000 r--p 00125000 fe:00 81937      /lib/libc-2.5.1.so
b7ee6000-b7ee7000 rw-p 00127000 fe:00 81937      /lib/libc-2.5.1.so
b7ee7000-b7eeb000 rw-p b7ee7000 00:00 0
b7ef3000-b7ef4000 rw-p b7ef3000 00:00 0
b7ef4000-b7ef5000 r-xp b7ef4000 00:00 0          [vdso]
b7ef5000-b7f0f000 r-xp 00000000 fe:00 81960      /lib/ld-2.5.1.so
b7f0f000-b7f10000 r--p 00019000 fe:00 81960      /lib/ld-2.5.1.so
b7f10000-b7f11000 rw-p 0001a000 fe:00 81960      /lib/ld-2.5.1.so
bff47000-bff5d000 rw-p bff47000 00:00 0          [stack]

这次堆确实是接着bss段开始,往上长的,这个吻合,但共享库仍然是放在栈下面的
搞不懂了

论坛徽章:
0
7 [报告]
发表于 2007-09-15 20:09 |只看该作者
两次malloc返回值说明不了任何问题呀

论坛徽章:
0
8 [报告]
发表于 2007-09-15 20:38 |只看该作者
原帖由 flw2 于 2007-9-15 20:09 发表
两次malloc返回值说明不了任何问题呀


主要是我看书,说在Linux进程虚拟地址空间里,共享库放在0x40000000处,堆从bss段结束处开始,往上长,而malloc就是管理堆空间的,
而这跟我平台上的实验结果出入较大,理解不了,有疑惑,
不明白malloc分配的空间是怎么管理的,可否解惑?
多谢

论坛徽章:
0
9 [报告]
发表于 2007-09-15 21:29 |只看该作者

回复 #8 augustusqing 的帖子

我在多台机器上做了实验,无论一次分配多大的内存,堆都是向上增长的,重现不了lz的结果。
其次,共享库确实是放在栈的下面,堆的上面,CSAPP也是这样讲的,不知lz的疑惑在哪儿。
最后,对于malloc的机制,CSAPP的动态储存器分配一节有讲,lz把第10章读完就可以看到,另外,一本经典的C语言教程《C program language》的附录中给出了malloc一种实现的例子,lz也可以看看。

另外,lz应该把虚拟地址空间和虚拟内存两个概念区分开,它们完全不相同。虚拟地址空间是描述进程资源的一个集合,例如你cat map文件看到的就是对进程虚拟地址空间map关系的描述。虚拟内存如楼上几位所讲,就是个swap机制。你可以在安装系统的时候不指定swap分区来关掉虚拟内存,但你不能使你的进程没有虚拟地址空间,除非你的程序始终运行在实模式下。

[ 本帖最后由 zx_wing 于 2007-9-15 21:33 编辑 ]

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
10 [报告]
发表于 2007-09-15 22:34 |只看该作者
原帖由 augustusqing 于 2007-9-15 19:45 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7355876&ptid=991328][/url]
# ./test &
[1] 1775
lfslivecd:root | 2007年09月15日 星期六 19时30分28秒 | /mnt/lfs/sources
# PID: 1775
ptr: 0x804a000
ptr: 0xb6dd9008
ptr: 0xb5dd8008
ptr: 0x804a000

lfslivecd:root | 2007年09月15日 星期六 19时30分29秒 | /mnt/lfs/sources
# cat /proc/1775/maps
08048000-08049000 r-xp 00000000 08:02 780348     /mnt/lfs/sources/test
08049000-0804a000 rw-p 00000000 08:02 780348     /mnt/lfs/sources/test
b5dd8000-b7ddb000 rw-p b5dd8000 00:00 0
b7ddb000-b7f00000 r-xp 00000000 fe:00 81937      /lib/libc-2.5.1.so
b7f00000-b7f02000 r--p 00125000 fe:00 81937      /lib/libc-2.5.1.so
b7f02000-b7f03000 rw-p 00127000 fe:00 81937      /lib/libc-2.5.1.so
b7f03000-b7f07000 rw-p b7f03000 00:00 0
b7f0f000-b7f10000 rw-p b7f0f000 00:00 0
b7f10000-b7f11000 r-xp b7f10000 00:00 0          [vdso]
b7f11000-b7f2b000 r-xp 00000000 fe:00 81960      /lib/ld-2.5.1.so
b7f2b000-b7f2c000 r--p 00019000 fe:00 81960      /lib/ld-2.5.1.so
b7f2c000-b7f2d000 rw-p 0001a000 fe:00 81960      /lib/ld-2.5.1.so
bfc03000-bfc19000 rw-p bfc03000 00:00 0          [stack]





00000000
00000000
b5dd8000
00000000
00125000
00127000
................

这列表示的是什么?文件偏移么?


而且:
ptr: 0x804a000
ptr: 0xb6dd9008
ptr: 0xb5dd8008
ptr: 0x804a000
这里边第一行和第四行一样,根本没有从堆里分配过空间.

也许是/lib/ld-2.5.1.so在加载/lib/libc-2.5.1.so时, /lib/libc-2.5.1.so初始化的时候匿名影射了[b5dd8000, b7ddb000 ].不清楚.但反正是没有用过堆.

为什么你最后一个区间是[bfc03000, bfc19000] ? 这个好象也不是栈,而是interpreter的bss段.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP