在 SIGSEGV 之后映射未分配的内存

问题描述 投票:0回答:1

通过信号处理程序捕获 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;
}
c segmentation-fault mmap
1个回答
0
投票

导致分段错误(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;
}

(还没测试)

© www.soinside.com 2019 - 2024. All rights reserved.