Chinaunix

标题: APUE中给出的abort函数实现的疑惑 [打印本页]

作者: hewangping    时间: 2006-10-17 10:34
标题: APUE中给出的abort函数实现的疑惑
各位大虾:
    看这段代码时,百思不得其解。具体请看下面代码:

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

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 */

    /*
     * If we're here, process caught SIGABRT and returned.
     */
    fflush(NULL);               /* flush all open stdio streams */
    /*为什么这里要重新设置信号处理函数并再次发送SIGABRT信号呢?为什么不直接exit*/
    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 */
    exit(1);    /* this should never be executed ... */
}
作者: hewangping    时间: 2006-10-19 10:01
没有人回答啊。顶一下
作者: wolf0403    时间: 2006-10-20 00:25
因为 POSIX 要求 abort 函数通过发送 SIGABRT 使进程退出。之前的代码判断 SIGABRT 对应的响应如果是 SIG_IGN,则恢复成 SIG_DFL;同时取消可能的 sigprocmask 掩码;但是如果 SIGABRT 被制定了其它的自定义响应函数,则会正常执行一次并且成功返回。如果出现这种情况,进程就会运行到
  1.    /*
  2.      * If we're here, process caught SIGABRT and returned.
  3.      */
复制代码

的位置。这时强制恢复默认行为并从新触发一次,迫使进程出错退出。

:)
作者: hewangping    时间: 2006-10-20 13:15
多谢楼上的。
你的意思是说/* If we're here, process caught SIGABRT and returned.*/前面的是为了在调用者定义了自己的响应函数的情况下让调用者的响应函数执行。后面的则是让SIG_DFL处理ABORT信号,而SIG_DFL的处理结果是退出进程,所以最后的exit(1)后面注释说 “this should never be executed ... ”。不知道我这样理解对不对?:)
作者: pengphy    时间: 2009-11-11 12:27
The abort() function causes abnormal program termination unless the signal SIGABRT is caught and the signal handler does not return.
作者: shiyang1212    时间: 2010-08-06 16:01
根据各位的解释,我的理解是如果第一个Kill之前信号SIGABRT默认的不是SIG_IGN,那么第一次Kill发出的信号并不能是当前程序终止。那么程序就会重新安装信号处理程序,再次发送SIGABRT信号使当前进程终止
不知道是否是这么理解的。不过我的疑问是既然不能确定是否第一次执行Kill是是否是安装的SIG_IGN那么为什么不直接再次安装了再使用kill,以免第二次使用kill?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2