【问题标题】:using siglongjmp effectively有效地使用 siglongjmp
【发布时间】:2012-04-26 17:41:32
【问题描述】:

我有一个类似 shell 的程序,它在循环中运行;它接受很少的命令并执行所需的功能。 程序仅在调用“getout”命令时退出。

让我们假设如果发生分段错误信号,我只是处理清理我的程序,而不是退出程序,我只想留在里面。 我可以使用 siglongjmp() 调用来实现这一点。

我的问题:当我在恢复函数中再次运行我的 shell 程序时,当现在发生任何分段错误时,我的信号没有被捕获以进行清理并且程序以分段错误退出。

请提出解决方案:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <setjmp.h>
sigjmp_buf mark;

void myhandler(int signo)
{
my_action();
siglongjmp(mark,-1);
}

recover()
{
my_program_loop();
}

my_program_loop()
{
/* accept some commands and do some functionality*/
/*some part of the code may cause segfault*/
}


main()
{
     if (sigsetjmp(mark,0) != 0)
    {
        printf("siglongjmp() is called\n");
        recover();
        exit(1);
    }

    struct sigaction myhandle;
    myhandle.sa_handler = myhandler;
    sigemptyset(&myhandle.sa_mask);
    myhandle.sa_flags = 0;
    sigaction(SEGSEGV, &myhandle, NULL);

    my_program_loop();

}

请帮忙。

【问题讨论】:

  • 首先避免获取SIGSEGV。使用gcc -Wall -g 编译您的代码并使用gdb 进行调试。也许使用valgrind 来追踪内存错误。
  • 大声笑,得到了解决方案。为了着急,我没有保存当前的信号掩码。在使用 sigsetjmp(sigjmp_buf env, int savemask) 时,如果 savemask 参数的值不为 0,sigsetjmp() 也会将调用线程的当前信号掩码保存为调用环境的一部分。在上面的代码中,在 main() 中,如果 sigsetjmp(mark,0) 应该修改为 sigsetjmp(mark,1) 并且它工作得很好

标签: c linux signals


【解决方案1】:

你的 « my_program_loop » 应该有问题,我可以用这段代码很好地捕捉到信号:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <setjmp.h>

sigjmp_buf mark;

void myhandler(int signo) {
    printf("Sig caught\n");
    siglongjmp(mark, -1);
}

void my_program_loop(void) {
    char *p = NULL;
    *p = 5;
}

void recover(void) {
    my_program_loop();
}

int main(void) {
    struct sigaction myhandle;

    if (sigsetjmp(mark, 0) == -1) {
        recover();
        exit(1);
    }

    myhandle.sa_handler = myhandler;
    sigemptyset(&myhandle.sa_mask);
    myhandle.sa_flags = 0;
    sigaction(SIGSEGV, &myhandle, NULL);

    my_program_loop();

    return 0;
}

【讨论】:

  • 我可以知道你是否每次都能抓住它吗?
  • 在我看来你只能抓住它一次
猜你喜欢
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多