0

重複の可能性:
mmap後にmemcpyでセグメンテーション違反SIGSEGVを取得する

私はcppコードでmmap()を使用して、大きなサイズの領域(100,000,000バイト〜100MB)をマップしています。

man mmapからは、成功したかどうかしかわからないこと、マッピングに成功したサイズがわからないことがわかります。

私の場合、8192バイトのバッファーを使用してその領域を繰り返し読み取ることができましたが、約24MBを読み取った後、SIGSEGVが取得されます。これは、mmapが領域全体を正常にマップしなかったことを意味しますか?

memcpy関数を使用して、マップされた領域からヒープ上のバッファーにコピーしています。(バッファがスタック上にある場合にも同じ動作が見られます)。

エリア全体がマッピングされているかどうかはどうすればわかりますか?また、エリア全体をマッピングした場合、約24MBのバイトを読み取った後にSIGSEGVを取得するのはなぜですか?

ありがとう!

4

2 に答える 2

6
int *  addr = reinterpret_cast<int *>(mmap(NULL, length , PROT_READ, flags , fd, 0));
// ...    
int * initaddr = addr;

char buffer[jbuffer_size];

void *ret_val = buffer;
int read_length = length;

while(ret_val == buffer || read_length<jbuffer_size) {
    ret_val = memcpy(buffer, addr,jbuffer_size);
    addr+=jbuffer_size;
    read_length -= jbuffer_size;
}

したがって、終了条件は間違っているように見えます。デクリメントして、。 未満read_lengthになるまでループします。 buffer_size

また、バイトではなく整数(これは)でインクリメントaddrしています。つまり、4倍速く進んでいます。buffer_size int*addr

ところで、他のコードでは:lseekを取り、返すのoff_tではなく、を返しますsize_t


編集:これらのバグのほとんどはすでに他の質問で指摘されているので、これが何かを追加するかどうかはわかりません。

于 2012-11-07T17:13:31.513 に答える
2

セグメンテーション違反が発生した場合、それmmapは成功しなかったためではなく、他の何かが原因です。プロセスの仮想メモリにマップされているリージョン外のセグメントにアクセスしようとしています。

プログラムのメモリアクセスを、プログラムが割り当てたマップのセットと照合します。pmap、、straceおよびを活用することを検討してくださいgdb

于 2012-11-07T17:00:36.613 に答える