判断内存地址是否缺页

一个进程的内存是否加载到物理内存,系统是有记录的。记录文件就是/proc/$pid/pagemap

pagemap和内存地址的对应关系:

file_offset = virt_addr / PAGE_SIZE * PAGEMAP_ENTRY;

8字节的PAGEMAP_ENTRY用于记录这一页的内存映射信息:

    * Bits 0-54  page frame number (PFN) if present

    * Bits 0-4   swap type if swapped

    * Bits 5-54  swap offset if swapped

    * Bit  55    pte is soft-dirty (see Documentation/vm/soft-dirty.txt)

    * Bit  56    page exclusively mapped (since 4.2)

    * Bits 57-60 zero

    * Bit  61    page is file-page or shared-anon (since 3.5)

    * Bit  62    page swapped

    * Bit  63    page present


完整代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
         const  int  __endian_bit = 1 ;
         #define PAGEMAP_ENTRY 8
         #define is_bigendian () ( (*( char *)&__endian_bit) == 0 ) 
         #define GET_BIT (X,Y) (X & ((uint64_t)1<<Y)) >> Y
         #define GET_PFN (X) X & 0x7FFFFFFFFFFFFF
         char  page_path [0xff] = {0};
         snprintf(page_path,  sizeof (page_path ) - 1 ,  "/proc/%u/pagemap" , getpid());
         FILE * f =  fopen (page_path,  "rb" ); //open(page_path, O_RDONLY);
         if (! f)  return  -1;
         unsigned  long  file_offset = addr /  PAGE_SIZE * PAGEMAP_ENTRY;
         int  status =  fseek (f, file_offset, SEEK_SET);
         unsigned  char  c_buf [PAGEMAP_ENTRY];
         for int  i = 0; i < PAGEMAP_ENTRY; i++)
         {
             int  c =  getc (f);
             if ( c == EOF)  return  -1;
             if (is_bigendian()) c_buf[ i] = c;
             else  c_buf [PAGEMAP_ENTRY - i -1] = c;
         }
         
         unsigned  long  long  read_val = 0;
         for int  i = 0; i < PAGEMAP_ENTRY; i++)
         {
             read_val = ( read_val << 8) + c_buf[ i]; 
         }
 
         if (GET_BIT( read_val, 63))
            printf ( "PFN: 0x%llx" ,(unsigned  long  long ) GET_PFN(read_val));
         else
            printf "page not present" );
 
         if (GET_BIT( read_val, 62))
            printf "Result: 0x%llx" ,  read_val );
         fclose (f);

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值