程序运行提示 退出(吐核)

/* sigactdemo.c
 *               purpose: shows use of sigaction()
 *               feature: blocks ^\ while handling ^C
 *                        does not reset ^C handler, so two kill
 */

#include    <stdio.h>
#include    <signal.h>
#define    INPUTLEN    100

main()
{
    struct sigaction newhandler;            /* new settings        */
    sigset_t         blocked;               /* set of blocked sigs */
    void         inthandler();          /* the handler         */
    char         x[INPUTLEN];

    /* load these two members first */
    newhandler.sa_handler = inthandler;      /* handler function    */
    newhandler.sa_flags = SA_RESETHAND | SA_RESTART;  /* options    */

    /* then build the list of blocked signals */
    sigemptyset(&blocked);                  /* clear all bits      */
    sigaddset(&blocked, SIGQUIT);        /* add SIGQUIT to list */

    newhandler.sa_mask = blocked;        /* store blockmask     */

    if ( sigaction(SIGINT, &newhandler, NULL) == -1 )
        perror("sigaction");
    else
        while( 1 ){
            fgets(x, INPUTLEN, stdin);
            printf("input: %s", x);
        }
}

void inthandler(int s)
{
    printf("Called with signal %d\n", s);
    sleep(s);
    printf("done handling signal %d\n", s);
}

Unix/Linux系统编程实践教程一书P205页例子,上面使用函数sigaction,主要是演示在处理SIGINT(ctrl + C)时阻塞SIGQUIT(ctrl + ),搜了下结构体sigcation中sa_mask的作用是要阻塞的信号当在处理时,因此用sigaddset等函数添加了SIGQUIT信号,可是执行时却报错

[root@centos-linux-7 CH07]# ./sigactdemo 
^\退出(吐核)
[root@centos-linux-7 CH07]# gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
目标:x86_64-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
线程模型:posix
gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
[root@centos-linux-7 CH07]# 
阅读 4.7k
1 个回答

代码没有问题。

默认情况下,SIGQUIT 信号导致进程终止,并产生 Core Dump,即你所描述的“吐核”。

当进程被 SIGINT 信号中断时,由于设置 sa_mask 屏蔽了 SIGQUIT,因此进程不会马上终止,它将在 SIGINT 信号处理完成后进行。

你可以把 sa_mask 清空做一次对比,两次的操作流程都一样,如下

  1. 运行编译的文件
  2. 按下 Ctrl + c ,这将产生 SIGINT 信号
  3. 待显示出 “Called with signal 2” 时,按下 Ctrl + \,这将产生 SIGQUIT 信号

以下是运行结果

  • 屏蔽了 SIGQUIT
^CCalled with signal 2
^\done handling signal 2
[N]    NNN quit (core dumped)  ./xxx
  • 没有屏蔽 SIGQUIT
^CCalled with signal 2
^\[N]    NNN quit (core dumped)  ./xxx
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题