使用信号和sigsegjmp / siglongjmp捕获SIGSEGV

时间:2013-01-24 02:40:23

标签: c signals sigsegv

我正在编写一个小程序来扫描内存的每个页面上的单个内存,以查看它是否可读/可读/无。

注意:我没有显示代码的一部分,因为它导致错误的信号handeling。

这个循环用于浏览addys

char * currAddy;
currAddy = (char*)0x00000000;

while(1){

    int readWrite = read_write(currAddy);

    printf("Chunk val returned %i\n", readWrite);

    if(currAddy == (char*)0xfffff000)
        break;

    currAddy += pageSize;

}

其余用于处理信号

int read_write (char * currAddy)
{

myRead = 0;
myWrite = 0;

/*
 myRead = 0 & myWrite = 0 -> NOT A CHUNK -> RW = -1
 myRead = 0 & myWrite = 1 -> NOT POSSIBLE
 myRead = 1 & myWrite = 0 -> RW = 0
 myRead = 1 & myWrite = 1 -> RW = 1

 */

if (sigsetjmp(jumpbuf, 1) == 0){

    //try and read
    char test = *currAddy;
    myRead = 1;

    //try and write
    *currAddy = 'a';
    myWrite = 1;


}else{

    //SIGSEGV while reading
    if (myRead == 0)
        return -1;

    //SIGSEGV while writing
    if (myRead == 1 && myWrite == 0)
        return 0;

    printf("Inside setjmp\n");

}

printf("Below the sigjmp\n");
sleep(1);

//return 1 because we can both read and write to this position

//doesnt appear to run though -- HELP HERE?
return 1;

}

这是处理信号的地方

void handler (int sig)
{
    siglongjmp(jumpbuf, 1);
}

现在,当我运行此输出时,输出如下:

Chunk val returned -1
Chunk val returned -1
Chunk val returned -1
Chunk val returned 0
Chunk val returned 0
Below the sigjmp
Inside setjmp
Below the sigjmp
Below the sigjmp
Inside setjmp
Below the sigjmp
Below the sigjmp
Inside setjmp
.........

编辑:我似乎无法弄清楚为什么它永远不会返回1?同样奇怪的是它如何打印“在sigjmp下面”两次。任何帮助/提示将不胜感激!

1 个答案:

答案 0 :(得分:0)

对于POSIX,你不能在信号处理程序中使用(sig)longjump - 如果你这样做,你会得到未定义的行为。但是至少有一些Unix确实允许它(通常是BSD派生的),所以你在这里看到的内容取决于你运行的是什么操作系统。

看起来你在sleep调用中遇到崩溃(可能是由于早期siglongjmp中的信号/堆栈状态已损坏)导致它循环回sigsetjmp

成功的*currAddy = 'a';也有可能破坏重要的东西,导致后来的崩溃循环回到sigsetjmp