mmap EPERM错误

时间:2012-10-04 19:57:32

标签: linux mmap

我有一个简单的mmap程序,它在两台linux机器上表现不同:

  

cat a.c

   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <errno.h>


   #include <sys/mman.h>
   #include <err.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>

   int
   main(void)
   {
           int fd = -1;
           char *A, *zero;

           if ((fd = open("./a.out", O_RDONLY, 0)) == -1)
                   exit(1);

           A = mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, fd, 0);

           if (A == MAP_FAILED)
              printf("error %d, errno=%d\n", A, errno);
           else
               printf("OK %d\n", A);
           return (EXIT_SUCCESS);
   }

在一台机器上mmap返回成功,但是另一台机器打印错误(errno为1)。

strace结果的相关差异是:

好的:(2.6.9-78.ELsmp#1 SMP Wed Jul 9 15:46:26 EDT 2008 x86_64 x86_64 x86_64 GNU / Linux) 打开(“./ a.out”,O_RDONLY)= 3 mmap(NULL,65536,PROT_READ | PROT_EXEC,MAP_PRIVATE | MAP_FIXED | MAP_DENYWRITE,3,0)= 0

失败的一个:(2.6.18-194.26.1.el5#1 SMP Fri Oct 29 14:21:16 EDT 2010 x86_64 x86_64 x86_64 GNU / Linux) 打开(“./ a.out”,O_RDONLY)= 3 mmap(NULL,65536,PROT_READ | PROT_EXEC,MAP_PRIVATE | MAP_FIXED | MAP_DENYWRITE,3,0)= -1 EPERM(不允许操作)

在失败的那个中,如果我摆脱MAP_FIXED标志,mmap会成功。似乎失败的进程没有可用于映射的内存空间[0,65535]。

我不知道在哪里可以找到这个问题?可能是造成不同行为和失败的原因是什么?或者更具体地说,如果我猜测失败是由于不可用[0,65535],那么一台机器可以使用它而另一台机器不可用的原因是什么?感谢

感谢

2 个答案:

答案 0 :(得分:0)

根据手册页[Doesn't] interpret addr as a hint: place the mapping at exactly that address.

mmap MAP_FIXED。在您的示例中,[addr] ess为NULL(第一个mmap参数)。

NULL几乎总是映射到零页,因此EPERM可能是预期的响应。

它以前的工作情况可能是一个错误(A是否映射到包含文件内容的零页?)

答案 1 :(得分:0)

您指定的MAP_FIXED地址为零。默认情况下,在最新版本的Linux上,并且可以在某些早期版本上进行配置,禁止在低虚拟地址处进行映射,以防止利用内核空指针取消引用错误。