2017-08-20 40 views
1

我试图使用mmap分配内存,这里是代码:MMAP分配收益0xfffffffffffffff4(不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); 

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

更奇怪的行为:

我试图打印errno。如果我使用printf("%d\n", errno);它打印0,指针仍然设置为0xfffffffffffffff4。但是,如果使用err(errno, "%p", copy);然后它打印:

program.exe: 0x7f8130981000: Success 

而现在的指针是有效的,但我不能使用它,因为err终止执行。

+0

'program.exe' - 你在Windows上吗?你正在使用MinGW或Cygwin或其他? –

+0

不,我可以看到如何可以误导,我在Linux上,但我指定.exe扩展为组织目的 – Hadron

+2

您的问题可能是'mmap'返回的转换。在C中,这是不必要的,可以隐藏错误。也许你忘了'#include '?也许你没有切换全部的警告? “墙”可以告诉你更多。 –

回答

0

当编译所有的警告(-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra),如评论建议,我意识到<err.h>不包括在内。当我把它包括在内时,我在问题结尾处描述的“奇怪行为”消失了;程序表现正常,但仍然有一个不好的指针,我不知道它,但在这一点上,如果我没有检查errno,程序将工作。

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

因此,看着为该功能生成的汇编代码,我意识到%rbx没有被编译器“保护”。添加到标头<errno.h>固定,现在一切工作正常。

即使它看起来没有适当的包含工作,这是一个更加小心的教训,并始终使用最大的警告选项。

+0

你是什么意思的“未被保护”? 'rbx'是一个被保存的被调用的寄存器,如果您在手写汇编中使用它,保存和恢复它是您的工作。您在手动编写汇编程序之前应该知道这一点。 – Art

+0

现在的事情是,所有正确的头文件都已包含在内(并且汇编器函数没有改变)。我不知道为什么。我注意到,当包含正确的文件时,在调用'mmap()'之前''rsp''已经多了一个字节的coupe,可能是覆盖问题。 – Hadron