强制页面边界Segfault?

时间:2014-08-26 13:39:16

标签: c++ linux

我想编写一个测试(gcc 4.7),其中我分配了一个内存页面,它以某种方式位于我的进程不拥有的内存页面旁边,这样通过页面末尾的未对齐读取应该是段错误的。

这可能吗?我该怎么做?

2 个答案:

答案 0 :(得分:3)

您可以mprotect使用保护= PROT_NONE来使网页无法访问,例如

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

int main(void)
{
    char * a = valloc(4096 * 2);            // page-aligned memory allocation (two pages)

    int status = mprotect(&a[4096], 4096, PROT_NONE);
    if (status != 0) { perror("mprotect"); exit(1); }
                                            // protect second page

    for (int i = 0; i <= 4096; i += 256)    // test - should fail when i == 4096
    {
        printf("a[%d] = %u\n", i, a[i]);
    }

    return 0;
}

编译和测试:

$ gcc -Wall mprotect.c && ./a.out 
a[0] = 0
a[256] = 0
a[512] = 0
a[768] = 0
a[1024] = 0
a[1280] = 0
a[1536] = 0
a[1792] = 0
a[2048] = 0
a[2304] = 0
a[2560] = 0
a[2816] = 0
a[3072] = 0
a[3328] = 0
a[3584] = 0
a[3840] = 0
Bus error: 10
$ 

请注意,当我们尝试阅读a[4096]时会生成总线错误。

如果你在gdb下运行它,你会得到更多信息:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000000100803000
0x0000000100000eff in main () at mprotect.c:14
14          printf("a[%d] = %u\n", i, a[i]);

答案 1 :(得分:0)

我认为没有简单的方法可以保证电话会出现段错误。

从少数语言来看,分配(拥有)内存之外的所有访问都是undefined behaviour。访问的结果甚至是未定义但经常?一个段错误,但并非总是如此。因此,保罗提供的解决方案有时可以完成这项工作,但不能作为保证。

如果您在valgrind的控制下运行您的工作,您可以始终获得访问您不拥有的内存的段错误。但这不是默认行为。您还可以使用更多的库(如efence或其他库)来捕获这些错误。来自较新编译器版本的memory-sanitize也是一个起点。

作为对你的问题的回答:不,没有办法保证简单的c语句的段错误。