/proc/$pid/maps文件中各个空间段的意义

一、从/proc/self/maps中看到的内存布局

在这个输出中,可以很容易看到一个so文件中有一个"---p"属性的区间段,它们对应哪些文件内容,数据从哪里来?在stackoverflow网站上也有一个这样的提问,只是还没有人解答。
[email protected]: cat /proc/self/maps
00400000-0040b000 r-xp 00000000 fd:01 15433 /usr/bin/cat
0060b000-0060c000 r--p 0000b000 fd:01 15433 /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 fd:01 15433 /usr/bin/cat
00877000-00898000 rw-p 00000000 00:00 0 [heap]
7fab3ae42000-7fab4136b000 r--p 00000000 fd:01 24801 /usr/lib/locale/locale-archive
7fab4136b000-7fab4136d000 r-xp 00000000 fd:01 25150 /usr/lib64/libdl-2.17.so
7fab4136d000-7fab4156d000 ---p 00002000 fd:01 25150 /usr/lib64/libdl-2.17.so
7fab4156d000-7fab4156e000 r--p 00002000 fd:01 25150 /usr/lib64/libdl-2.17.so
7fab4156e000-7fab4156f000 rw-p 00003000 fd:01 25150 /usr/lib64/libdl-2.17.so
7fab4156f000-7fab41729000 r-xp 00000000 fd:01 25054 /usr/lib64/libc-2.17.so
7fab41729000-7fab41928000 ---p 001ba000 fd:01 25054 /usr/lib64/libc-2.17.so
7fab41928000-7fab4192c000 r--p 001b9000 fd:01 25054 /usr/lib64/libc-2.17.so
7fab4192c000-7fab4192e000 rw-p 001bd000 fd:01 25054 /usr/lib64/libc-2.17.so
7fab4192e000-7fab41933000 rw-p 00000000 00:00 0
7fab41933000-7fab41954000 r-xp 00000000 fd:01 24864 /usr/lib64/ld-2.17.so

二、从lib文件看布局

从生成的so文件来看,两个LOAD节的Align都是0x20000,也就是2Mb的对齐,并且在第二个LOAD中,它的VirtAddr地址0x0000000000200db8,和文件偏移量0x0000000000000db8的起始地址相差了2M,而"---p"的区间段就是两个LOAD区间中空闲的内存空间。
[email protected]: cat -n maps---p.cpp
1 int gx = 1;
2 int gy;
3 int foo()
4 {
5 return gx + gy;
6 }
[email protected]: g++ maps---p.cpp -shared -fpic -o libmaps.so
[email protected]: readelf -l libmaps.so

Elf 文件类型为 DYN (共享目标文件)
入口点 0x630
共有 7 个程序头,开始于偏移量64

程序头:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000000007c4 0x00000000000007c4 R E 200000
LOAD 0x0000000000000db8 0x0000000000200db8 0x0000000000200db8
0x0000000000000274 0x0000000000000280 RW 200000
DYNAMIC 0x0000000000000dd8 0x0000000000200dd8 0x0000000000200dd8
0x00000000000001f0 0x00000000000001f0 RW 8
NOTE 0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
0x0000000000000024 0x0000000000000024 R 4
GNU_EH_FRAME 0x0000000000000740 0x0000000000000740 0x0000000000000740
0x000000000000001c 0x000000000000001c R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x0000000000000db8 0x0000000000200db8 0x0000000000200db8
0x0000000000000248 0x0000000000000248 R 1

三、这个Align为什么这么大

可以看到,这个对齐其实是在链接器中设置的,估计是为了兼容SO可以运行的平台,例如有些页面为2M的平台。这个大小可以通过链接器选项来设置
[email protected]: g++ maps---p.cpp -shared -fpic -o libmaps.so -Wl,-z,max-page-size=4096
[email protected]: readelf -l libmaps.so

Elf 文件类型为 DYN (共享目标文件)
入口点 0x630
共有 7 个程序头,开始于偏移量64

程序头:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000000007c4 0x00000000000007c4 R E 1000
LOAD 0x0000000000000db8 0x0000000000001db8 0x0000000000001db8
0x0000000000000274 0x0000000000000280 RW 1000
DYNAMIC 0x0000000000000dd8 0x0000000000001dd8 0x0000000000001dd8
0x00000000000001f0 0x00000000000001f0 RW 8

四、运行下看内存布局

可以看到中间已经没有"---p"属性区间段
[email protected]: cat -n main.cpp
1 int main()
2 {
3 int foo();
4 return foo();
5 }
[email protected]: g++ main.cpp -L`pwd` -lmaps -g
[email protected]: LD_LIBRARY_PATH=`pwd` gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/harry/study/maps---p/a.out...done.
(gdb) b main
Breakpoint 1 at 0x4006c4: file main.cpp, line 4.
(gdb) r
Starting program: /home/harry/study/maps---p/./a.out

Breakpoint 1, main () at main.cpp:4
4 return foo();
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.tl2.3.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64
(gdb) info proc
process 21541
cmdline = ‘/home/harry/study/maps---p/./a.out‘
cwd = ‘/home/harry/study/maps---p‘
exe = ‘/home/harry/study/maps---p/a.out‘
(gdb) shell cat /proc/21541/maps
00400000-00401000 r-xp 00000000 fd:10 31719450 /home/harry/study/maps---p/a.out
00600000-00601000 r--p 00000000 fd:10 31719450 /home/harry/study/maps---p/a.out
00601000-00602000 rw-p 00001000 fd:10 31719450 /home/harry/study/maps---p/a.out
……
7ffff7eef000-7ffff7ef0000 r-xp 00000000 fd:10 31719449 /home/harry/study/maps---p/libmaps.so
7ffff7ef0000-7ffff7ef1000 r--p 00000000 fd:10 31719449 /home/harry/study/maps---p/libmaps.so
7ffff7ef1000-7ffff7ef2000 rw-p 00001000 fd:10 31719449 /home/harry/study/maps---p/libmaps.so

五、"rw-p"为什么有两段

可以看到,在这个区间段的最后有两段,这一点也容易理解:
因为一些全局为初始化变量是位于bss段的,它们并不在文件中占用空间,需要在加载时清零。所以做文件映射就不能实现该功能(因为文件里没有对应的内容),所以这里其实是映射到了一个匿名的私有空间,逻辑地址空间和前面的连续。
7ffff7ad3000-7ffff7bbc000 r-xp 00000000 fd:01 25828 /usr/lib64/libstdc++.so.6.0.19
7ffff7bbc000-7ffff7dbc000 ---p 000e9000 fd:01 25828 /usr/lib64/libstdc++.so.6.0.19
7ffff7dbc000-7ffff7dc4000 r--p 000e9000 fd:01 25828 /usr/lib64/libstdc++.so.6.0.19
7ffff7dc4000-7ffff7dc6000 rw-p 000f1000 fd:01 25828 /usr/lib64/libstdc++.so.6.0.19
7ffff7dc6000-7ffff7ddb000 rw-p 00000000 00:00 0

原文地址:https://www.cnblogs.com/tsecer/p/11376415.html

时间: 2024-10-12 11:39:26

/proc/$pid/maps文件中各个空间段的意义的相关文章

awk 解析maps文件中的地址

maps文件一般是这个样子: [email protected]:~ $ sudo cat /proc/1/maps 54b88000-54c8d000 r-xp 00000000 b3:07 655537 /lib/systemd/systemd 54c9c000-54cac000 r--p 00104000 b3:07 655537 /lib/systemd/systemd 54cac000-54cad000 rw-p 00114000 b3:07 655537 /lib/systemd/s

删除大日志文件中的某段数据

using System; using System.IO; using System.Linq; using System.Text; namespace TestMultyConsole2 { public class LocalFileHelper { /// <summary> /// 删除大日志文件中的某些数据 /// </summary> /// <param name="filePath">源文件路径</param> ///

/proc/$PID/maps文件解读

Each row in /proc/$PID/maps describes a region of contiguous virtual memory in a process or thread. Each row has the following fields: address perms offset dev inode pathname 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm address - This is

linux proc maps文件分析

Proc/pid/maps显示进程映射了的内存区域和访问权限.对应内核中的操作集为proc_pid_maps_op,具体的导出函数为show_map.内核中进程的一段地址空间用一个vm_area_struct结构体表示,所有地址空间存储在task->mm->mmap链表中. 一个文件可以映射到进程的一段内存区域中,映射的文件描述符保存在vm_area_struct->vm_file域中,这种内存区域叫做有名内存区域,相反,属于匿名映射内存区域.Vm_area_struct每项对应解析如下

向PE文件中添加一个Section

背景 之前说过直接向类HelloWorld.exe的可执行文件添加一个MessageBox弹窗, 但有时候, 需要添加的内容太多了, 因为数据与代码一起插入, 以至于可执行文件本身没有足够的空闲空间存放这些内容时, 就需要添加一个Section. 确认节区头后面还有空间 用工具查看一下最后一个节区头后面是否还有多余的空间, 一般情况都会有的. 但若没有的话, 就要移动节区头后面的文件内容, 这个比较复杂, 在这里不说. 一般会结合PE View 和 WinHex 这两个工具, 如之前的Hello

Linux高级调试与优化——同时抓取coredump和maps文件

Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specify a core dumpfile pattern name. . max length 128 characters; default value is "core" . core_pattern is used as a pattern template for the output

ora-01652无法通过128(在表空间temp中)扩展temp段

今天提交请求后,提示ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段.最后通过ALTER DATABASE TEMPFILE '/*/*/db/apps_st/data/tempx01.dbf' RESIZE 7168M;扩展临时表空间来解决 今天提交请求后,提示ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段.最后通过ALTER DATABASE TEMPFILE '/*/*/db/apps_st/data/tempx

Linux中删除文件,磁盘空间未释放问题追踪

在客户使用我们产品后,发现一个问题:在删除了文件后,磁盘空间却没有释放.是有进程在打开这个文件,还是其他情况?我们一起来看看一下两个场景 一. 场景一:进程打开此文件 当一个文件正在被一个进程使用时,用户删除此文件,文件只会从目录结构中删除,但并没有从磁盘删除.当使用这个文件的进程结束后,文件才会真正的从磁盘删除,释放占有的空间. 我们发现剩余磁盘空间比较少时,回去删除一些大的临时文件或者log文件,如果删除之后会发现磁盘空间并未减少,那么可以通过"lsof"命令去查看正在使用该文件的

数据库逻辑存储结构管理(5)-存储-表空间段区块

查看表空间信息SELECT * FROM V$TABLESPACE 查看表空间数据文件路径信息SELECT * FROM DBA_DATA_FILES; 查看表空间的属性信息SELECT * FROM DBA_TABLESPACES 查看表空间组及其所属的表空间的信息SELECT * FROM DBA_TABLESPACE_GROUPS查看表空间里面的表的组成SELECT SEGMENT_NAME,SEGMENT_TYPE,TABLESPACE_NAME FROM DBA_SEGMENTS WH