3

ループで実行されるプログラムのようなシェルがあります。いくつかのコマンドを受け入れ、必要な機能を実行します。プログラムは、「getout」コマンドが呼び出されたときにのみ終了します。

セグメンテーション違反の信号が発生した場合、プログラムのクリーンアップを処理し、プログラムを終了する代わりに、内部に留まりたいと考えてみましょう。siglongjmp()呼び出しを使用してこれを達成できます。

私の問題:リカバリ関数でシェルプログラムを再度実行し、セグメンテーションフォールトが発生した場合、クリーンアップのためにシグナルがキャッチされず、プログラムがセグメンテーションフォールトで終了します。

解決策を提案してください:

#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();

}

助けてください。

4

1 に答える 1

2

« 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;
}
于 2012-04-26T09:41:32.523 に答える