使用信号中止功能实现

kum*_*ran 3 c c++ unix linux signals

下面是abort使用signals"Unix中的高级编程"中给出的功能实现示例.以下代码中几乎没有疑问 -


void    abort(void)         /* POSIX-style abort() function */
{
    sigset_t           mask;
    struct sigaction   action;

    /*
     * Caller can't ignore SIGABRT, if so reset to default.
     */
    sigaction(SIGABRT, NULL, &action);
    if (action.sa_handler == SIG_IGN) {
        action.sa_handler = SIG_DFL;
        sigaction(SIGABRT, &action, NULL);
    }
    if (action.sa_handler == SIG_DFL)
        fflush(NULL);           /* flush all open stdio streams */

    /*
     * Caller can't block SIGABRT; make sure it's unblocked.
     */
    sigfillset(&mask);
    sigdelset(&mask, SIGABRT);  /* mask has only SIGABRT turned off */
    sigprocmask(SIG_SETMASK, &mask, NULL);
    kill(getpid(), SIGABRT);    /* send the signal */ **STEP 1**

    /*
     * If we're here, process caught SIGABRT and returned.
     */
    fflush(NULL);               /* flush all open stdio streams */
    action.sa_handler = SIG_DFL;
    sigaction(SIGABRT, &action, NULL);  /* reset to default */
    sigprocmask(SIG_SETMASK, &mask, NULL);  /* just in case ... */
    kill(getpid(), SIGABRT);                /* and one more time */ **STEP 2**
    exit(1);    /* this should never be executed ... */
}
Run Code Online (Sandbox Code Playgroud)

问题
a.当我们发送第一killSIGABRT(由第1步标记),为什么我们期待码继续下一行?(参见评论 - ' 如果我们在这里,进程抓住SIGABRT并返回 ')

湾 为什么我们需要kill再次发送信号(在步骤2中)然后exit(1)不应该被击中.(参考代码中的评论)

Bas*_*tch 5

大多数程序都没有做任何特别的事情SIGABRT.

但是一些奇怪的程序可以安装自己的信号处理程序SIGABRT,并且该abort功能应该仍然有效,即使对于它们也是如此.

所以大多数程序SIGABRT- 没有捕获- 不会超过第1步(因为默认行为SIGABRT是转储核心,根据信号(7) ......).

捕获的少数程序SIGABRT将持续到第2步(如果打电话给你abort).此时,SIGABRT已重新安装默认行为.所以程序转储核心在第2步.并且最终exit(1)无法到达.