我试图理解为什么在受内存保护的区域上调用写操作不会触发sigsegv
。考虑一下这个例子:
void *map_addr;
unsigned long addr;
map_addr = (void *)mmap(NULL, 0x4000, PROT_READ_WRITE, MAP_PRIVATE, fd, 0);
mprotect(map_addr, 0x4000, PROT_NONE);
addr = (unsigned long)map_addr;
// case 1:
*(volatile int*)(addr); // sigsegv sent
// case 2:
write(STDOUT_FILENO, map_addr, size); // sigsegv NOT sent
不是发送sigsegv
,而是在此实例中写入,返回-1
并设置errno=EFAULT
。为什么写有这种行为?我想象写会尝试从地址读取,这会产生sigsegv错误,但显然不是这样。
答案 0 :(得分:7)
write
是系统调用,因此内存访问发生在内核中,而不是在您的进程中。内核首先检查传递的地址是否对调用进程有效,如果不是,则只返回EFAULT
。
(我不知道为什么它的设计是这样的。)