mmap分配返回0xfffffffffffffff4(不是MAP_FAILED)

时间:2017-08-20 19:51:21

标签: c linux mmap errno

我正在尝试使用mmap分配内存,这是代码:

long long *copy;
copy = (long long*)mmap(NULL,
                       (size_t)1024,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_PRIVATE | MAP_ANON, -1, 0);

  if (copy == MAP_FAILED) {
    fprintf(stderr, "Memory allocation failed (Process aborted)\n");
    exit(1);
  }
  printf("Pointer: %p\n", copy);

显然,我检查分配是否失败。当发生这种情况时,我应该从man pages收集的内容得到-1。事情是我得到-12,好0xfffffffffffffff4,所以错误没有被捕获,程序继续。我想也许是因为(long long*)强制转换,但是强制转换不应该改变指针值。所以我很好奇为什么会发生这种情况以及如何防止它。

更奇怪的行为:

我尝试打印errno。如果我使用printf("%d\n", errno);它会打印0并且指针仍然设置为0xfffffffffffffff4。但如果我使用err(errno, "%p", copy);,则打印出来:

program.exe: 0x7f8130981000: Success

现在指针有效,但由于err终止执行,我无法使用它。

1 个答案:

答案 0 :(得分:0)

根据评论中的建议编译所有警告(.tags-panel)时,我意识到-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra未包括在内。当我把它包括在内时,我在问题的最后描述的“奇怪的行为”消失了;程序运行正常,但仍然有一个坏指针,我不知道它,但在这一点上,如果我没有检查<err.h>,该程序将起作用。

在代码的其他部分,我有汇编编写的函数,这些函数一直很好用(这就是为什么我认为错误与它们无关)。但后来我记得有些人使用errno在他们之间传递信息,但恰好%rbx是gcc中%rbx使用的寄存器。

所以看一下该函数生成的汇编代码,我意识到errno没有被编译器“保护”。添加到标题%rbx修复了它,现在一切正常。

即使它似乎没有适当的包含,但这绝对是一个教训,要更加小心,并始终使用最大警告选项。