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



我正在尝试使用 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: %pn", copy);

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

更奇怪的行为:

我试图打印errno.如果我使用printf("%dn", errno);它会打印 0,指针仍设置为0xfffffffffffffff4.但是如果我使用err(errno, "%p", copy);那么它会打印:

program.exe: 0x7f8130981000: Success

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

在编译所有警告(-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra(时,正如评论中所建议的那样,我意识到<err.h>不包括在内。当我把它包括在内时,我在问题末尾描述的"奇怪行为"消失了;该程序运行正常,但指针仍然不好,我不知道,但是如果我不检查errno,该程序就可以工作了。

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

因此,查看该函数生成的汇编代码,我意识到%rbx不受编译器的"保护"。添加到标题<errno.h>修复了这个问题,现在一切正常。

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

最新更新