通过信号处理程序捕获 SIGSEGV 后,我尝试使用
mmap
来映射地址。我不明白为什么 mmap
失败并出现 Cannot allocate memory
错误。
这是C代码。我正在尝试在 macOS 上运行它。
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
void *addr;
static void catch_function(int signo, siginfo_t *si, void *unused) {
printf("Got SIGSEGV at address: 0x%lx\n", (long)si->si_addr);
void *ptr = mmap(addr, 100, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANON | MAP_FIXED, 0, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
}
}
int main(void) {
int page_size = getpagesize();
if (signal(SIGSEGV, catch_function) == SIG_ERR) {
fputs("An error occurred while setting a signal handler.\n", stderr);
return 1;
}
addr = (void *)(page_size * 100);
// trigger segfault
*((int *)addr) = 1;
}
导致分段错误(SIGSEGV) 的原因是尝试写入无效的内存地址。
在你的花瓶中,我认为
addr
变量被设置为未分配的内存地址。
这是更新后的代码:
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
void *addr;
static void catch_function(int signo, siginfo_t *si, void *unused) {
printf("Got SIGSEGV at address: 0x%lx\n", (long)si->si_addr);
void *ptr = mmap(NULL, 100, PROT_READ | PROT_WRITE, // Here
MAP_SHARED | MAP_ANON, -1, 0); // Here
if (ptr == MAP_FAILED) {
perror("mmap");
} else {
addr = ptr; // Here
}
}
int main(void) {
int page_size = getpagesize();
if (signal(SIGSEGV, catch_function) == SIG_ERR) {
fputs("An error occurred while setting a signal handler.\n", stderr);
return 1;
}
addr = (void *)(page_size * 100);
// trigger segfault
*((int *)addr) = 1;
}
(还没测试)