前两天,有同事发现一个奇怪的BUG,简化来说,有两个进程:A和B。当使用kill -9将进程B杀掉后,进程A有时也会退出,但有时不会,概率性出现。
问题抛到我这,我之前也没有看过进程A和进程B的实现代码,不清楚他们之间有什么关联。
我的解题思路:
1. 确认在进程A、B都正常运行的时候,不会有哪个会突然退出? --- 经确认不存在
2. 确认就是在杀掉进程B后,进程A概率性退出? ---- 经过多次测试,确认进程A的概率性退出只和进程B有关。
3. 在确认问题复现路径后,思考一个进程为什么会突然退出呢?
a. 程序自身逻辑导致的退出,比如达到某个条件,调用 exit()退出; --- 经确认不存在
b. 程序内存使用异常,触发段错误,导致退出; --- 经确认,没有看到segment fault的错误打印
c. 程序收到了外部发送的死亡信号,比如 kill 或 Ctrl+C;--- 经确认,没有发送这类信号
d. 列出其他可能导致程序退出的signal,逐一分析对应的场景。综合现象来看,最有可能是SIGPIPE信号导致的进程退出。SIGPIPE信号产生的场景,比如两个进程通过socket通信,如果对端进程突然退出,这边进程在使用已经建立的socket通路发送数据时,就会得到一个SIGPIPE信号,默认操作就是终止进程。
通过阅读进程A和进程B的代码,发现他们之间确实使用了socket通信。
解决办法:忽略SIGPIPE信号即可,signal(SIGPIPE,SIG_IGN),一行代码搞定。
SIGABRT 进程停止运行
SIGALRM 警告钟
SIGFPE 算述运算例外
SIGHUP 系统挂断
SIGILL 非法指令
SIGINT 终端中断
SIGKILL 停止进程(此信号不能被忽略或捕获)
SIGPIPE 向没有读的管道写入数据
SIGSEGV 无效内存段访问
SIGQOUT 终端退出
SIGTERM 终止
SIGUSR1 用户定义信号
SIGUSR2 用户定义信号
SIGCHLD 子进程已经停止或退出
SIGCONT 如果被停止则继续执行
SIGSTOP 停止执行
SIGTSTP 终端停止信号