我有一个简单的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],那么一台机器可以使用它而另一台机器不可用的原因是什么?感谢
感谢
答案 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上,并且可以在某些早期版本上进行配置,禁止在低虚拟地址处进行映射,以防止利用内核空指针取消引用错误。