从进程的角度看内存

描述

在windows下的可执行文件的格式为.exe,而Linux的下的是ELF。这是一种文件格式,就是告诉你文件是怎么存储的。

整个ELF的图看看

代码

这些内容和内核空间定义也差不多。

代码段(.text):程序源代码编译后的机器指令被存放在这个代码段里。

数据段(.data):存放已初始化的全局变量和已初始化的局部静态变量。

bss段(.bss):用来存放未初始化的全局变量以及未初始化的局部静态变量。

写一个程序,其实是依赖很多的其他的程序,因此自己写的程序需要编译链接后才能使用。

时起到辅助作用,暂时先不用关注它们。程序在编译链接时会尽量把相同权限属性的段分配在同一个空间里,例如,把可读可执行的段放在一起,包括代码段、init段等;把可读可写的段放在一起,包括.data段和.bss段等。ELF把这些属性相似并且链接在一起的段叫作分段(Segment),进程在装载时是按照这些分段来映射可执行文件的。

描述这些分段的结构叫作程序头(Program Header),它描述了ELF文件是如何映射到进程地址空间的,这是我们比较关心的。

可以使用objdump或者readelf工具来查看ELF文件包含哪些段。

我们可以通过“readelf -l”命令来查看这些程序头。

在看的时候主要关注LOAD类型的分段,其他的都是在LOAD的时候起到辅助作用。

这是都是静态的。

在如果你想去看看静态的,可以通过proc文件系统来看看Linux内核的运行情况。每个进程运行之后,在/proc/pid/maps节点会列出当前进程的地址映射情况。

代码

第1行中显示了地址0x10000~0x870000这段进程地址空间,它的属性是只读并且可执行的,由此我们知道它是代码段,也就是之前看到的代码段的程序头。

第2行中显示了地址0x96000~0x98000,它的属性是可读可写的进程地址空间,也就是我们之前看到的数据段的程序头。

第 3 行中显示了地址0x98000~0xbb000,这段进程地址空间叫作堆空间(Heap),也就是通常使用malloc分配的内存,大小是140KB。test进程主要使用malloc分配100KB的内存,这里看到Linux内核会分配比100KB稍微大一点的内存空间。

第4行显示test进程的栈(stack)空间。

第5行是Sigpage的进程地址空间,Sigpage是ARM体系结构中特有的页面。

第6行是ARM中高端映射的异常向量(vectors)。

这里说的进程地址空间,在 Linux 内核中使用一个叫作 VMA的术语来描述,它是vm_area_struct数据结构的简称,在虚拟内存管理部分会详细介绍它。另外,/proc/pid/smaps节点会提供更多的地址映射的细节,以代码段的VMA和堆的VMA为例。

另外,/proc/pid/smaps节点会提供更多的地址映射的细节,以代码段的VMA和堆的VMA为例。

代码

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分