2

我不想处理分段错误。我或多或少地了解异常处理的工作原理。我宁愿一开始就没有错。我想要做的是调用一个函数或执行一个返回一个值的操作,该值告诉我该特定内存位置/块是否可访问,而无需实际访问它并获得故障。

也就是说,我想要一个 C 函数在实际访问它之前探测 Linux 和/或 Mac OS X 中的地址。就像是:

result = probe_memory(address,length)

结果在哪里

 0 = writable
 1 = read-only
-1 = nonexistent

或类似的规定。

在 Linux 和/或 Mac OS X 中有类似的东西吗?

4

3 回答 3

3

我相信或多或少像下面这样的东西应该起作用:

int probe_memory(void *address, size_t length) {
    int result, fd[2];

    pipe(fd);  /* Remember to check for errors! */

    errno = 0;
    result = write(fd[1], address, length);

    if (result < 0 || (size_t)result != length || errno == EFAULT) {
        result = 0;
    } else {
        result = 1;
    }

    close(fd[0]);
    close(fd[1]);

    return result;
}

这是您问题的部分解决方案,因为此代码不检查页面保护。

基本思想是让操作系统通过调用来读取length字节。如果内存不可访问,它将返回而不触发段错误。addresswriteEFAULT

Jonathan Leffler在他的Stack Overflow Questions 存储库中编写了一个完整的实现。

于 2013-09-18T03:59:40.673 回答
1

您可以使用mincore(2)并且可以顺序读取和 parse /proc/self/maps,请参阅proc(5)

请注意,Linux 并非旨在快速提供此类映射信息。众所周知,模拟应用程序分页(如 GNU/Hurd 外部寻呼机...)很慢。(例如,通过一些低级的、特定于处理器的SIGSEGV处理程序)。

如果您的唯一目的是提供关于 的回溯信息,您可以使用来自 GCC 源代码SIGSEGV的 Ian Taylor 的libbacktrace 。

正如一些评论所说,也许你想要valgrind

于 2013-09-18T04:47:02.123 回答
0

您忘记了响应列表 - 可写但操作系统正在使用/某些关键的东西/实际上是内存映射自毁等。

您最好的选择是尝试让您编写防弹代码,其中一部分是您写到拥有的位置。

分配、检查、复制、修改可能最终会更快、更可靠、更便携和更易于维护,而不是试图扭曲操作系统臂以提供所需的信息,而不是尝试自己检查。

于 2013-09-18T05:04:02.343 回答