C mmap分配返回0xFFFFFFFFFFF4(非映射失败)
我正在尝试使用mmap分配内存,下面是代码:C mmap分配返回0xFFFFFFFFFFF4(非映射失败),c,linux,mmap,errno,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)
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);
显然,我会检查分配是否失败。当这种情况发生时,我应该从我收集的数据中得到-1。问题是我得到了-12,好的0xfffffffffff4
,这样错误就不会被捕获,程序继续运行。我想这可能是因为(long-long*)
强制转换,但是强制转换不应该改变指针值。所以我很好奇为什么会发生这种情况,以及如何预防它
更奇怪的行为:
我试图打印errno
。如果我使用printf(“%d\n”,errno)
它打印0,指针仍然设置为0xfffffffffff4
。但是如果我使用err(errno,“%p”,copy)代码>然后打印:
program.exe: 0x7f8130981000: Success
现在指针是有效的,但我不能使用它,因为err
终止了执行。当编译时,所有警告(-Wmissing-prototype-Wstrict-prototype-Werror-Wextra
),正如注释中建议的那样,我意识到
没有包括在内。当我把它包括进来时,我在问题末尾描述的“奇怪行为”消失了;程序运行正常,但指针仍然不正确,我不知道,但在这一点上,如果我不检查errno
,程序就会工作
在代码的其他部分,我有汇编编写的函数,它们一直工作得很好(这就是为什么我认为错误与它们无关)。但是我记得有些人使用%rbx
在他们之间传递信息,但碰巧的是%rbx
是gcc中用于errno
的寄存器
因此,查看为该函数生成的汇编代码,我意识到%rbx
不受编译器的“保护”。添加到标题
修复了这一问题,现在一切正常
即使它似乎在没有适当的include的情况下工作,但这无疑是一个教训,需要更加小心,始终使用最大的警告选项。您的问题很可能是mmap
返回的演员。在C语言中,这是不必要的,并且可以隐藏bug。也许你忘了把
#包括在内?也许你还没有打开所有的警告-Wall
可以告诉您更多。通过提供MCVE,您可能会得到更好的帮助:您是否尝试过使用-Wmissing prototype-Wstrict prototype-Werror-Wextra
以及-Wall
进行编译?同样,如果您已经包含了必要的标题,这不会改变任何事情-如果您是一个细心的编码者。如果您没有包含必要的标题,或者您是一个粗心的程序员,那么您可能要做的工作比您预期的要多。(我一直在使用这些选项;我没有机会成为一个粗心的程序员——至少,不会因为这些选项识别出的错误而遇到问题。)此外,如果使用warnc()
而不是err()
,会发生什么?我强烈建议使用原型选项——它可以防止此类问题。不包括
使其以不同的、更具创造性的方式失败-您不知道打印的指针err()
是否有效,因为程序已退出。我没有经常看到像您看到的那样的行为(除了在proto-MCVE中),特别是当包含正确的头和声明函数时。在Linux(以及一些,也许许多其他系统)上,错误12是ENOMEM。是否存在使用有趣的映射函数将-1
错误代码转换为-errno
的危险?变得古怪…在linux上编译时,始终启用所有警告。至少使用:gcc-c-ggdb-Wall-Wextra-pedantic-Wconversion-std=gnu11 myprogram.c-o myprogram.o
rbx
是一个被调用方保存的寄存器,如果您在手写程序集中使用它,您的工作就是保存和恢复它。在手工编写汇编程序之前,您应该知道这一点。问题是,现在已经包含了所有正确的头文件(并且汇编程序函数没有更改),它就可以工作了。我不知道为什么。我注意到,当包含正确的文件时,%rsp
在调用mmap()
之前又减少了几个字节,可能存在覆盖问题。