提问人:user16217248 提问时间:6/17/2023 最后编辑:user16217248 更新时间:6/17/2023 访问量:109
如何使用 mmap() 确定是否所有映射页面都有效?
How can I determine if all mapped pages while using mmap() are valid?
问:
我了解到,即使调用返回成功,分配的页面也可能不可用。例如,如果正在映射一个文件,并且传递给 mmap()
的 len
足够大于该文件。在这种情况下,超出文件使用的页面的任何页面,即使在请求的大小内,如果尝试使用它们,也会产生一个。mmap()
SIGBUS
有没有办法直接确定从映射开始到的所有字节是否可以安全访问?除了手动测量文件的长度,或设置处理程序,或以其他方式(详尽地)检查是否满足页面无法访问的任何原因之外,我还可以这样做吗?len
SIGBUS
// Assuming PAGE_SIZE == 4096
int fd = open("file", O_RDONLY);
void *buffer = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
// Is there any way to determine if reading bytes 4093-8192 will cause a bus error?
// Besides measuring if the size of the file is greater than 4092?
我是否可以直接确定是否有任何页面因任何原因不可用,而不是检查文件大小以确定是否有任何页面因文件太小而不可用?
答:
0赞
user16217248
6/17/2023
#1
规范的方法是无论如何都只用于测量文件的大小,如果文件太小,则失败。没有更“直接”的方法来查询页面的可用性,也不需要这样的方法,因为手册页在 Signals 下显示,唯一的方法是文件太小:fstat()
SIGBUS
SIGBUS Attempted access to a page of the buffer that lies beyond the end of the mapped file. For an explanation of the treatment of the bytes in the page that corresponds to the end of a mapped file that is not a multiple of the page size, see NOTES.
以下代码是如何安全使用的示例:mmap()
#define PAGE_ALIGN(S) ((S)+PAGE_SIZE-1&~(PAGE_SIZE-1))
#define EXPECTED_SIZE /* ... */
int fd = open("file", O_RDONLY);
struct stat statbuf;
if (fstat(fd, &statbuf) || PAGE_ALIGN(statbuf.st_size) < EXPECTED_SIZE)
return EXIT_FAILURE;
void *mapping = mmap(NULL, EXPECTED_SIZE, PROT_READ, MAP_SHARED, fd, 0);
if (mapping == MAP_FAILED)
return EXIT_FAILURE;
评论
fstat
ftruncate
mmap
strace -o /tmp/out.txt ls
ls
open()
fstat()
mmap()