2013年4月8日星期一

一个逗号引发的血案


一个 C 模块,单模块压力没有出任何问题,链系统一压力,稳定复现不出 core 挂掉.
挂在 gdb 下压力后发现挂掉时的一条信息: Program received signal SIGPIPE, Broken pipe.
谷歌了一番,发现是 SIGPIPE 信号没有屏蔽掉.反复查看代码, main 函数有 signalsetup(); 一行,显示有屏蔽函数,可总是无法忽略 kill -SIGPIPE .怀疑原来的屏蔽方法有问题,又从网上找了段大家一致认为靠谱的方法:

    struct sigaction sa;
    
sa.sa_handler SIG_IGN;//设定接受到指定信号后的动作为忽略
    
sa.sa_flags   0;
    if (
sigemptyset(&sa.sa_mask) == -||   //初始化信号集为空
            
sigaction(SIGPIPE, &sa0) == -1)
    {   
//屏蔽SIGPIPE信号
        
fprintf(stderr"failed to ignore SIGPIPE; sigaction\n");
        exit(
EXIT_FAILURE);
    }



结果也不行.于是把代码单独拿出来编译来执行,却发现可以实现信号屏蔽.
求助同事,他建议将屏蔽信号函数的调用往后放置,排除非一些初始化操作的干扰.将 signalsetup(); 这一行后置编译时发现语法错误,编译不过,原来错将一个 ; 打做 ,了:

400     pthread_t *pt_server_core, pt_server_run,
401
402     signalsetup();

就这样,一个逗号让我折腾了大半天,引发一场惨烈的血案,血的教训.
编译器版本: gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)
据朋友说,新版本的 gcc 能检测到如此低级的错误.我用老版本在编译时却没有给出相应的警告.

没有评论: