【问题标题】:`mprotect` fails after many invocations多次调用后`mprotect`失败
【发布时间】:2014-04-23 01:19:25
【问题描述】:

我在我的程序中经常调用mprotect,但我发现程序在一段时间后失败了。我猜是因为mprotect调用太多,所以我写了一个测试来验证:

#define pagesize 4096
int main(){
  while(1){
     buffer = memalign(pagesize, 4 * pagesize);// allocate some buffer
     mprotect(buffer, pagesize, PROT_NONE)// make the first page inaccessible
  }
}

大约 30,000 次迭代后,mprotect 返回 -1,无论缓冲区大小如何。

谁能解释为什么以及如何解决它?我的猜测是 mprogtect 消耗内核资源并且每个进程都有一些限制,但不确定。

【问题讨论】:

  • 你的机器有多少内存?问题可能出在分配而不是保护上?
  • 一般来说,在调试此类问题时,您应该遵循通常的方法:重新编译内核并启用任何必要的调试选项(例如 CONFIG_DEBUG_VM 或 CONFIG_DEBUG_PAGEALLOC 或其他),然后密切监视dmesg 输出,可能在使用串口控制台的远程机器上。
  • @oakad 我的 32 位 ubuntu 上有 4G 内存。 30K * 4K * 4 = 480M。所以它不应该是由于用户空间或RAM中的虚拟地址空间的限制,对吧?
  • 问一问总不会有什么坏处。在程序挂起之前,您是否在dmesg 收到任何投诉?
  • @oakad 谢谢。但我们在 dmesg 中一无所获。

标签: linux memory-management linux-kernel


【解决方案1】:

显然,有一个内核参数控制进程可以拥有的不同映射的数量,可在/proc/sys/vm/max_map_count 获得。大多数发行版上的典型默认映射数是 64k - 与 mprotect 在大约 30k 次迭代时失败一致(每个 memalign 一个映射,每个 mprotect 另一个映射 + 一些正常的系统映射)。增加该限制将允许您分配和保护更多内存区域。

【讨论】:

  • 它有效。非常感谢。而这个link 告诉我们如何临时或永久增加限制max_map_count。
  • @Infinite 链接现在失效了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 2016-02-09
相关资源
最近更新 更多