进程,可执行文件和内存的关系

假设我们有如下程序:

#include <stdio.h>

int bss;
int data = 10;

void f(unsigned long *a)
{
        *a = 1;
}

int main(int argc, char*argv[])
{
        int stack;
        void *heap;
        printf("bss: %p\n", &bss);
        printf("data: %p\n", &data);
        printf("f: %p\n", f);
        printf("stack: %p\n", &stack);
        heap = malloc(10);
        printf("heap: %p\n", heap);

        sleep(10000);

        return 0;
}

输出如下:

# ./test
bss: 0x60103c
data: 0x601034
f: 0x400567
stack: 0x7ffc2946b944
heap: 0x8f7670
# objdump -h test
 12 .text         00000202  0000000000400490  0000000000400490  00000490  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 22 .data         00000008  0000000000601030  0000000000601030  00001030  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .bss          00000008  0000000000601038  0000000000601038  00001038  2**2
                  ALLOC
crash> ps | grep test
  10296  10585  10  ffff880715539d00  IN   0.0    4476   1564  test
crash> task_struct.mm ffff880715539d00
    mm = 0xffff88072b3903c0
crash> mm_struct.mmap 0xffff88072b3903c0
  mmap = 0xffff8807154a0000
crash> list vm_area_struct.vm_next 0xffff8807154a0000 -s vm_area_struct.vm_start,vm_file                                            ffff8807154a0000
  vm_start = 0x400000
  vm_file = 0xffff88078396eb00
ffff8807154a1590
  vm_start = 0x600000
  vm_file = 0xffff88078396eb00
ffff8807154a08a0
  vm_start = 0x601000
  vm_file = 0xffff88078396eb00
ffff8807154a0cf0
  vm_start = 0x8f7000
  vm_file = 0x0
ffff8807154a1648
  vm_start = 0x7f942c678000
  vm_file = 0xffff88078396fa00
ffff8807154a0fd0
  vm_start = 0x7f942c853000
  vm_file = 0xffff88078396fa00
ffff8807154a11f8
  vm_start = 0x7f942ca53000
  vm_file = 0xffff88078396fa00
ffff8807154a0450
  vm_start = 0x7f942ca57000
  vm_file = 0xffff88078396fa00
ffff8807154a0228
  vm_start = 0x7f942ca59000
  vm_file = 0x0
ffff8807154a17b8
  vm_start = 0x7f942ca5d000
  vm_file = 0xffff88078396f000
ffff8807154a00b8
  vm_start = 0x7f942cc60000
  vm_file = 0x0
ffff8807154a1a98
  vm_start = 0x7f942cc82000
  vm_file = 0x0
ffff8807154a1140
  vm_start = 0x7f942cc84000
  vm_file = 0xffff88078396f000
ffff8807154a0da8
  vm_start = 0x7f942cc85000
  vm_file = 0xffff88078396f000
ffff8807154a0b80
  vm_start = 0x7f942cc86000
  vm_file = 0x0
ffff8807154a0ac8
  vm_start = 0x7ffc2944d000
  vm_file = 0x0
  vm_start = 0x7ffc2949d000
  vm_file = 0x0
ffff8807154a0c38
  vm_start = 0x7ffc294a0000
  vm_file = 0x0
crash> file 0xffff88078396eb00
struct file {
  f_u = {
    fu_llist = {
      next = 0x0
    },
    fu_rcuhead = {
      next = 0x0,
      func = 0x0
    }
  },
  f_path = {
    mnt = 0xffff8807c8eb8020,
    dentry = 0xffff8803c66118c0
  },
  f_inode = 0xffff88034e86aa98,
crash> inode.i_mapping 0xffff88034e86aa98
  i_mapping = 0xffff88034e86ac10
crash> address_space 0xffff88034e86ac10 -o
struct address_space {
  [ffff88034e86ac10] struct inode *host;
  [ffff88034e86ac18] struct radix_tree_root page_tree;
  [ffff88034e86ac28] spinlock_t tree_lock;
  [ffff88034e86ac2c] atomic_t i_mmap_writable;
  [ffff88034e86ac30] struct rb_root i_mmap;
  [ffff88034e86ac38] struct rw_semaphore i_mmap_rwsem;
  [ffff88034e86ac60] unsigned long nrpages;
  [ffff88034e86ac68] unsigned long nrexceptional;
  [ffff88034e86ac70] unsigned long writeback_index;
  [ffff88034e86ac78] const struct address_space_operations *a_ops;
  [ffff88034e86ac80] unsigned long flags;
  [ffff88034e86ac88] spinlock_t private_lock;
  [ffff88034e86ac8c] gfp_t gfp_mask;
  [ffff88034e86ac90] struct list_head private_list;
  [ffff88034e86aca0] void *private_data;
  [ffff88034e86aca8] errseq_t wb_err;
}
SIZE: 0xa0
crash> tree -t ra ffff88034e86ac18
ffffea001c506380
ffffea001c506340
ffffea000d685f80
crash> tree -t ra ffff88034e86ac18 -s page.mapping
ffffea001c506380
    mapping = 0xffff88034e86ac10
ffffea001c506340
    mapping = 0xffff88034e86ac10
ffffea000d685f80
    mapping = 0xffff88034e86ac10

系统调用do_execve通过do_mmap把可执行文件的各个section放到进程的某个线性地址中(vm_area_struct)。可执行文件8.1K,正好占用了三个内存页。这些内存页通过IDR存在address_space中。

# cat /proc/31845/maps
00400000-00401000 r-xp 00000000 fd:00 2200014                            /root/test/test
00600000-00601000 r--p 00000000 fd:00 2200014                            /root/test/test
00601000-00602000 rw-p 00001000 fd:00 2200014                            /root/test/test
00930000-00951000 rw-p 00000000 00:00 0                                  [heap]
7f8ec0fbd000-7f8ec1198000 r-xp 00000000 fd:00 134321644                  /usr/lib64/libc-2.26.so
7f8ec1198000-7f8ec1398000 ---p 001db000 fd:00 134321644                  /usr/lib64/libc-2.26.so
7f8ec1398000-7f8ec139c000 r--p 001db000 fd:00 134321644                  /usr/lib64/libc-2.26.so
7f8ec139c000-7f8ec139e000 rw-p 001df000 fd:00 134321644                  /usr/lib64/libc-2.26.so
7f8ec139e000-7f8ec13a2000 rw-p 00000000 00:00 0
7f8ec13a2000-7f8ec13ca000 r-xp 00000000 fd:00 134320668                  /usr/lib64/ld-2.26.so
7f8ec15a5000-7f8ec15a8000 rw-p 00000000 00:00 0
7f8ec15c7000-7f8ec15c9000 rw-p 00000000 00:00 0
7f8ec15c9000-7f8ec15ca000 r--p 00027000 fd:00 134320668                  /usr/lib64/ld-2.26.so
7f8ec15ca000-7f8ec15cb000 rw-p 00028000 fd:00 134320668                  /usr/lib64/ld-2.26.so
7f8ec15cb000-7f8ec15cc000 rw-p 00000000 00:00 0
7ffe1ee63000-7ffe1ee84000 rw-p 00000000 00:00 0                          [stack]
7ffe1ef5a000-7ffe1ef5d000 r--p 00000000 00:00 0                          [vvar]
7ffe1ef5d000-7ffe1ef5f000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值