c - C中的中止函数

标签 c linux unix 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");
}

输出 1:

$ ./a.out 
PID: 32235
Hai
Signal handled
Aborted (core dumped)
$

根据引用资料,中止函数的工作方式类似于 raise(SIGABRT)。因此,abort() 函数生成的信号是 SIGABRT。为此,我创建了上述程序。

在该程序中,SIGABRT 信号被处理。 signal handler执行后,并没有从调用的地方返回到main函数。 handler完成后为什么不返回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");
}

输出 2:

$ ./a.out 
PID: 32247
Hai
Hai
Hai
Signal handled
Hai
Signal handled
Hai
Hai
^C
$ 

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

$ kill -6 32247
$ kill -6 32247

因此,一旦信号发生,处理函数就会执行,然后返回到主函数。但是它不会发生在程序 1 中。为什么它会这样呢? abort函数和SIGABRT有什么不同?

最佳答案

请参阅 man 3 abort 中的这段文档:

This results in the abnormal termination of the process unless the SIGABRT signal is caught and the signal handler does not return (see longjmp(3)).

还有这个:

If the SIGABRT signal is ignored, or caught by a handler that returns, the abort() function will still terminate the process. It does this by restoring the default disposition for SIGABRT and then raising the signal for a second time.

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

关于c - C中的中止函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33566228/

相关文章:

c - 函数调用时出现段冲突错误

linux - 将一组文件重命名为 001、002、

c# - 无法连接到任何指定的 mysql C#

java - 使用Java Runtime API运行grep命令

c - C语言中指针操作的理解问题

c - 如何在c中制作while循环

python - PyErr_SetString 不会立即引发异常(Swig)?

linux - 显示套接字选项

linux - 在 AIX (Unix) 中解压 .zipx 格式

unix - 使用 tar 时排除目录