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 - 读取(fd,NULL,0);它有什么作用?它定义明确吗?

c - Matlab R2007b 未解析的外部与引擎实用程序

c - fprintf(long) 写入 8 个字节,而 fscanf(long) 读取 6 个字节,为什么?

linux - 为 ARM 编译 Linux 内核 3.2 时出错

linux - 计算csv文件的列数

c++ - "C"和 "extern C"之间的权限差异

linux - awk 不打印所需的 df 输出

linux - 如何读取文件并从一个文件复制到shell脚本中的另一个文件

Linux/Unix 手册页语法约定

linux - 在 bash 脚本中打开 pdf 文件的命令