调用pthread_kill()向指定线程发送SIGINT导致进程整体终止
多线程C应用SIGINT触发进程意外终止问题
我有一个大型多线程C应用(无法提供完整代码),核心场景是:线程1调用pthread_kill()向线程2发送SIGINT信号,此时线程2正处于ppoll()等待状态。预期线程2退出ppoll()并打印"Got EINTR"后继续运行,但实际进程直接终止。
相关代码
线程1代码
... if (thread && pthread_kill(&thread, SIGINT) != 0) { fprintf(log1, "Got error: %s", strerror((int)errno)); } ...
注:thread是存储线程2句柄的pthread_t类型变量
线程2代码
... sigset_t mask; int rc; sigemptyset(mask); ... while(true) { ... rc = ppoll(fds, nfds, NULL, mask); if (rc < 0) { if (errno == EINTR) fprintf(log2, "Got EINTR"); else fprintf(log2, "Got error: %s", strerror((int)errno)); continue; } fprintf(log, "%d descriptor(s) ready", rc); } ...
已知信息
- 代码此前运行正常,仅将数据加载源从Oracle(Pro*C实现)改为Postgres(libpq实现),线程及信号相关代码未改动
- 线程创建、信号收发的逻辑和顺序新旧版本完全一致,仅新版本发送SIGINT后进程终止,旧版本线程2正常处理并继续运行
- 可确认线程1是在线程2进入
ppoll()后才发送SIGINT - gdb调试确认目标线程收到了SIGINT,但未获取更多有效信息
- 编写最小复现示例未成功,示例中逻辑正常运行
排查思路
修正并验证信号掩码的正确性
- 首先注意线程2中
sigemptyset(mask)存在参数错误,sigemptyset的参数应为指针,正确写法是sigemptyset(&mask),错误写法会导致未定义行为,可能是新版本才暴露的问题 - 在
ppoll()调用前,用pthread_sigmask(SIG_BLOCK, NULL, ¤t_mask)获取线程2的当前信号掩码,打印确认SIGINT未被屏蔽 - 检查libpq初始化或运行过程中是否全局修改了进程/线程的信号掩码
- 首先注意线程2中
检查SIGINT的信号处理函数状态
- 用
sigaction查询当前SIGINT的处理函数,确认是否被libpq改为默认终止行为(SIG_DFL)——默认信号处理是进程级的,若未屏蔽SIGINT,任何线程收到信号都会触发进程终止 - 在新旧版本中分别对比主线程、线程2的SIGINT处理函数,看是否存在差异
- 用
排查libpq对线程和信号的影响
- 确认libpq是否创建了额外线程,这些线程是否未屏蔽SIGINT:即使使用
pthread_kill指定线程,若目标线程未屏蔽但其他线程也未屏蔽,信号可能被其他线程接收并触发默认处理 - 查看libpq核心函数(如
PQconnectdb、PQexec)是否有修改信号掩码或注册信号处理逻辑的代码,比如为中断连接而修改SIGINT处理 - 测试仅加载libpq但不建立数据库连接的场景,看问题是否重现,缩小排查范围
- 确认libpq是否创建了额外线程,这些线程是否未屏蔽SIGINT:即使使用
明确进程终止的具体原因
- 启用核心转储(
ulimit -c unlimited),生成core文件后用gdb分析,查看终止时的线程栈回溯,确认是哪个线程触发了进程终止 - 用gdb运行程序,进程终止时执行
info signals查看SIGINT的状态,执行bt full获取详细调用栈信息 - 检查是否存在SIGINT触发的连锁错误(如内存访问异常)导致进程终止
- 启用核心转储(
验证
ppoll调用的有效性- 确认
ppoll的参数(fds、nfds、mask)是否正确,替换ppoll为poll(配合pthread_sigmask手动屏蔽信号),看问题是否依然存在,排除ppoll本身的调用错误 - 检查
ppoll返回错误时的errno是否真的是EINTR,或者是否有其他错误被忽略后引发异常
- 确认
检查线程信号掩码的继承关系
- 确认线程2创建时是否继承了主线程的信号掩码,新版本中主线程的信号掩码是否因libpq的修改而发生变化
- 用
pthread_attr_getsigmask检查线程创建时的属性,确认信号掩码配置是否符合预期
内容的提问来源于stack exchange,提问作者Kekers_Dev
相关产品推荐
相关产品推荐

