如何防止(不作出反应)分段错误?

时间:2013-09-18 03:02:55

标签: c linux macos segmentation-fault

我不是在尝试处理分段错误。我理解异常处理是如何工作的,或多或少。我宁愿首先没有错。我想要做的是调用一个函数或执行一个返回值的操作,告诉我该特定的内存位置/块是否可访问,而不实际访问它并获得错误。

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

result = probe_memory(address,length)

结果是

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

或类似的东西。

在Linux和/或Mac OS X中有类似内容吗?

3 个答案:

答案 0 :(得分: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;
}
  

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

基本思路是让操作系统通过调用lengthaddress读取write个字节。如果内存不可访问,它将返回EFAULT而不会触发段错误。

Jonathan Leffler在他的Stack Overflow Questions repository

中写了一份完整的实施方案

答案 1 :(得分:1)

您可以使用mincore(2),然后按顺序阅读并解析/proc/self/maps,请参阅proc(5)

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

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

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

答案 2 :(得分:0)

你忘记了你的回复列表 - 可写但是在OS中使用/关键/实际上是内存映射自毁等等。

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

分配,检查,复制,修改可能最终变得更快,更可靠,更便携,更易于维护,试图扭转操作系统,提供所需信息,而不是试图自己检查