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接受并返回 a off_t,而不是 a size_t


编辑:大多数这些错误已经在另一个问题中指出,所以我不确定这个问题是否添加了任何东西。

于 2012-11-07T17:13:31.513 回答
2

如果您遇到分段违规,这不是因为mmap没有成功,而是因为其他原因。您正在尝试访问映射到进程虚拟内存的任何区域之外的段。

根据程序分配的映射集检查程序的内存访问。考虑利用pmap和。stracegdb

于 2012-11-07T17:00:36.613 回答