2017-08-20 41 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