当前位置: 首页 > 面试题库 >

如何知道写时复制页面是否为实际副本?

匡玉堂
2023-03-14
问题内容

当我使用mmap创建写时复制映射(MAP_PRIVATE)时,此映射的某些页面将在我写入特定地址后立即复制。在程序的某个时刻,我想弄清楚实际上已复制了哪些页面。有一个名为“
mincore”的调用,但仅报告该页面是否在内存中,这与正在复制的页面不同。

有什么办法可以确定哪些页面已被复制?


问题答案:

好的,按照MarkR的建议,我试了一下它来浏览pagemap和kpageflags界面。在一项快速测试下面,以检查页面是否在被调用时在内存中“SWAPBACKED”。当然,仍然存在一个问题,即kpageflags仅可由根访问的问题。

int main(int argc, char* argv[])
{
  unsigned long long pagesize=getpagesize();
  assert(pagesize>0);
  int pagecount=4;
  int filesize=pagesize*pagecount;
  int fd=open("test.dat", O_RDWR);
  if (fd<=0)
    {
      fd=open("test.dat", O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
      printf("Created test.dat testfile\n");
    }
  assert(fd);
  int err=ftruncate(fd,filesize);
  assert(!err);

  char* M=(char*)mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_PRIVATE,fd,0);
  assert(M!=(char*)-1);
  assert(M);
  printf("Successfully create private mapping\n");

测试设置包含4页。第0页和第2页脏了

  strcpy(M,"I feel so dirty\n");
  strcpy(M+pagesize*2,"Christ on crutches\n");

已读取第3页。

  char t=M[pagesize*3];

第1页将无法访问

页面映射文件将进程的虚拟内存映射到实际页面,然后可以从全局kpageflags文件中检索该页面。
读取文件/usr/src/linux/Documentation/vm/pagemap.txt

  int mapfd=open("/proc/self/pagemap",O_RDONLY);
  assert(mapfd>0);
  unsigned long long target=((unsigned long)(void*)M)/pagesize;
  err=lseek64(mapfd, target*8, SEEK_SET);
  assert(err==target*8);
  assert(sizeof(long long)==8);

在这里,我们读取了每个虚拟页面的页面框架编号

  unsigned long long page2pfn[pagecount];
  err=read(mapfd,page2pfn,sizeof(long long)*pagecount);
  if (err<0)
    perror("Reading pagemap");
  if(err!=pagecount*8)
    printf("Could only read %d bytes\n",err);

现在我们将为每个虚拟帧读取实际的页面标志

  int pageflags=open("/proc/kpageflags",O_RDONLY);
  assert(pageflags>0);
  for(int i = 0 ; i < pagecount; i++)
    {
      unsigned long long v2a=page2pfn[i];
      printf("Page: %d, flag %llx\n",i,page2pfn[i]);

      if(v2a&0x8000000000000000LL) // Is the virtual page present ?
        {
        unsigned long long pfn=v2a&0x3fffffffffffffLL;
        err=lseek64(pageflags,pfn*8,SEEK_SET);
        assert(err==pfn*8);
        unsigned long long pf;
        err=read(pageflags,&pf,8);
        assert(err==8);
        printf("pageflags are %llx with SWAPBACKED: %d\n",pf,(pf>>14)&1);
        }
    }
}

总而言之,我对这种方法并不特别满意,因为它需要访问我们通常无法访问的文件,而且它非常复杂(简单的内核调用来检索pageflags怎么样?)。



 类似资料:
  • (我已经删除了上一个,所以我想你可以在编辑中找到它) 编辑 所以按照bad_coder在评论中告诉的以及他分享的链接中的大多数答案,我点击了“选项显示所有”,我得到了这个 1) 这里唯一有意义的是点击“”按钮,所以我点击了它 2) 现在我应该用路径替换突出显示的部分(换句话说,我在cmd中键入“where python”后得到的路径) 3) 这就是我发现的。那么我应该在突出显示的部分复制并粘贴哪一

  • 当弹出权限对话框时,它会询问我是否要允许或拒绝某个权限。问题是,当我允许或拒绝时,动作不会执行。我如何知道他是否允许,以便我可以在接受时执行操作? 我试过: 但它没有执行,因为“为时已晚”

  • 问题内容: PDFbox内容流是按页面完成的,但是字段来自于来自目录的表单,该目录来自pdf doc本身。因此,我不确定哪些字段位于哪些页面上,以及导致将文本写到错误的位置/页面上的原因。 即。我正在处理每页的字段,但不确定哪些字段在哪些页面上。 有没有办法告诉哪个字段在哪个页面上?或者,是否有办法只获取当前页面上的字段? 谢谢! 标记 代码段: 问题答案: PDFbox内容流是按页面完成的,但是

  • 问题内容: 即使文件在远程http服务器上不存在,它也会以静默方式返回,它只是将html页面保存到命名文件中。例如: 即使abc.jpg在google.com服务器上不存在,它只是默默返回,生成的不是有效的jpg文件,它实际上是html页面。我猜返回的标头(一个httplib.HTTPMessage实例)可以用来实际上告诉检索是否成功,但是我找不到的任何文档。 有人可以提供有关此问题的一些信息吗?

  • 我正在做一个基本的游戏,如果我点击一张牌,就会显示一张图片。这些照片是随机挑选的。到目前为止,我已经将随机图片分配给一张卡片,卡片正面朝下显示。因此,如果我单击卡片,我希望显示指定的图片(在字典中)。 我想知道如何检测我是否点击了(卡片的)图像,因为图像的x,y坐标在左上角。现在,我正试图找到一种方法,使用鼠标点击的xy坐标来检测图像是否被点击。有没有一种方法可以使用“碰撞”或使事情变得太复杂?我

  • 我有一个带有,(”或)的表单,。。。下拉菜单()。。我想根据填充/检查的输入量显示不同的div。我写这篇文章是为了输入()按id选择输入id,但如何才能对和