私はメモリブロックを割り当て、ブロックのページサイズとページアラインされたサブセットの保護を選択的に変更するプログラムを作成しようとしています。しかし、ブロックに8ページ以上あるメモリ部分にmprotect
を呼び出そうとすると、mprotect
は "メモリを割り当てられません"というエラーで失敗します。私が見つけたいくつかの呼び出しの後にmprotectが失敗する
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
:次のようなメッセージを与えて、
#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:ここで
は、問題を再現し、最小限の完全な、かつ検証可能な例であります questionでは、OPが私と同じエラーを出すようですが、 David Hammenは問題の原因を示唆していますが、彼が何を話しているのか分かりません。残念ながら、OPはコードを提供していないので、彼らは何をしているのか、どうやって修正したのか正確には分かりません。基本的に私の質問です:なぜmprotect
はそのエラーを作りますか?どのように修正できますか?
「私は彼が何を話しているのか分かりません」 - 正確には何が分かりませんか? – melpomene
問題は、 'ENOMEM'(あなたが得るエラー)は3つの異なることを意味することがあり、意味するものがいつも分かりやすいとは限りません。 [mprotectのマニュアルページ](http://man7.org/linux/man-pages/man2/mprotect.2.html)の説明を読んだことがありますか?そこのケースの1つまたは好ましくは2つを排除できますか? –
@melpomeneページがマップされているかどうか、そしてページがマッピングされているかマップされていないかを確認することによって、彼が何を意味するのか分かりません:) –