受保护内存区域上的 write() 不会触发 sigsegv,但标准访问会触发
write() on protected memory region does not trigger sigsegv, but standard access does
我试图理解为什么在内存保护区域上调用写操作不会触发 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
,在这个实例中写入 returns -1
并设置 errno=EFAULT
。为什么 write 有这种行为?我想 write 会尝试从地址读取,这会造成 sigsegv 错误,但显然不是这种情况。
write
是一个系统调用,所以内存访问发生在内核中,而不是在你的进程中。内核首先检查传递的地址对于调用进程是否有效,如果不是,它只是 returns EFAULT
.
(虽然我不知道为什么它被设计成这样工作。)
我试图理解为什么在内存保护区域上调用写操作不会触发 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
,在这个实例中写入 returns -1
并设置 errno=EFAULT
。为什么 write 有这种行为?我想 write 会尝试从地址读取,这会造成 sigsegv 错误,但显然不是这种情况。
write
是一个系统调用,所以内存访问发生在内核中,而不是在你的进程中。内核首先检查传递的地址对于调用进程是否有效,如果不是,它只是 returns EFAULT
.
(虽然我不知道为什么它被设计成这样工作。)