我正在嘗試編寫一個程序,在該程序中分配一塊內存,然後有選擇地更改該塊的頁面大小和頁面對齊子集的保護。但是,當我嘗試在內存塊的大於8頁的部分內存中調用mprotect
時,mprotect
將失敗,並顯示錯誤「無法分配內存」。mprotect在撥打一定數量的電話後失敗
這裏是能重現問題最小,完整的,並且覈查例如:
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <cerrno>
#include <cstring>
#include <iostream>
int main() {
const int n_pages = 12;
const int page_size = sysconf(_SC_PAGE_SIZE); // 4096
const int block_size = n_pages * page_size; // 65536
char* block_addr = (char*)aligned_alloc(page_size, block_size);
char* chunks[n_pages];
char* pointer = block_addr;
for (int n = 0; n < n_pages; n++) {
pointer = pointer + (n * page_size);
chunks[n] = pointer;
}
std::cout << "Set chunks read-only.\n";
for (int n = 0; n < n_pages; n++) {
if (mprotect(chunks[n], page_size, PROT_READ) != 0) {
std::cerr << n+1 << '/' << n_pages << ' '
<< "mprotect failed: " << std::strerror(errno) << '\n';
}
}
std::cout << "Set chunks read/write.\n";
for (int n = 0; n < n_pages; n++) {
if (mprotect(chunks[n], page_size, PROT_READ|PROT_WRITE) != 0) {
std::cerr << n+1 << '/' << n_pages << ' '
<< "mprotect failed: " << std::strerror(errno) << '\n';
}
}
free(block_addr);
}
這始終未能對組塊N> 8,給出以下消息:
Set chunks read-only.
9/12 mprotect failed: Cannot allocate memory
10/12 mprotect failed: Cannot allocate memory
11/12 mprotect failed: Cannot allocate memory
12/12 mprotect failed: Cannot allocate memory
Set chunks read/write.
9/12 mprotect failed: Cannot allocate memory
10/12 mprotect failed: Cannot allocate memory
11/12 mprotect failed: Cannot allocate memory
12/12 mprotect failed: Cannot allocate memory
我發現了一個question其中OP似乎得到了與我相同的錯誤,其中David Hammen有用地提供了一些提示問題的根源,但我並不真正瞭解他在說什麼。不幸的是,OP沒有提供他們的代碼,所以我們無法確切知道他們在做什麼或者他們如何修復它。
所以基本上我的問題是:爲什麼mprotect
會產生這個錯誤,我該如何解決?
「*我真的不明白他在說什麼*」 - 究竟是什麼不清楚? – melpomene
問題是'ENOMEM'(你得到的錯誤)可能意味着三件不同的事情,並且知道它是什麼意思並不總是容易的。您是否閱讀過[mprotect'手冊頁]中的說明(http://man7.org/linux/man-pages/man2/mprotect.2.html)?你可以消除一個或最好兩個在那裏的情況? –
@melpomene我不明白他的意思是確保頁面已被映射,我的意思是頁面是或不被映射:) –