C中的中止功能

mrg*_*mrg 5 c unix linux abort

计划1:

#include<stdio.h>
#include<signal.h>
void handler(int sig);
void main()
{
    printf("PID: %d\n",getpid());
    signal(SIGABRT,handler);
    while(1){
        printf("Hai\n");
        sleep(1);
        abort();
    }
}

void handler(int sig)
{
    printf("Signal handled\n");
}
Run Code Online (Sandbox Code Playgroud)

输出1:

$ ./a.out 
PID: 32235
Hai
Signal handled
Aborted (core dumped)
$
Run Code Online (Sandbox Code Playgroud)

根据参考,中止功能的工作方式如下raise(SIGABRT).因此,abort()函数生成的信号是SIGABRT.为此,我创建了上述程序.

在该程序中,处理SIGABRT信号.在执行信号处理程序之后,它不会返回到调用它的主函数.处理程序完成后为什么不返回main函数?

计划2:

#include<stdio.h>
#include<signal.h>
void handler(int sig);
void main()
{
    printf("PID: %d\n",getpid());
    signal(SIGABRT,handler);
    while(1){
        printf("Hai\n");
        sleep(1);
    }
}

void handler(int sig)
{
    printf("Signal handled\n");
}
Run Code Online (Sandbox Code Playgroud)

输出2:

$ ./a.out 
PID: 32247
Hai
Hai
Hai
Signal handled
Hai
Signal handled
Hai
Hai
^C
$ 
Run Code Online (Sandbox Code Playgroud)

与程序1不同,程序2按预期执行.在上面的程序中,信号通过命令行通过kill命令发送到进程,如下所示.

$ kill -6 32247
$ kill -6 32247
Run Code Online (Sandbox Code Playgroud)

因此,一旦信号发生,执行处理程序函数,然后它返回到main函数.但它不会发生在程序1中.为什么它会像这样?该abort功能与SIGABRT有什么不同?

rod*_*igo 6

请参阅以下文档man 3 abort:

除非SIGABRT信号被捕获且信号处理程序没有返回(参见longjmp(3)),否则会导致进程异常终止.

而且这个:

如果SIGABRT信号被忽略,或被返回的处理程序捕获,该abort()函数仍将终止该进程.它通过恢复默认处置SIGABRT然后再次提升信号来实现此目的.

因此,防止abort()中止程序的唯一方法是通过longjmp()信号处理程序.


Som*_*ude 1

abort函数发送的SIGABRT信号是正确的,但如果您捕获(或忽略)该信号并不重要,该abort函数仍然会退出您的进程。

从链接的手册页:

返回值

abort()函数永远不会返回。