strace显示线程触发SIGSEGV但主进程以退出码0结束,原因何在?
问题分析:线程触发SIGSEGV但主进程正常退出(状态码0)
问题描述
对某进程执行strace时发现,部分线程触发了SIGSEGV信号,但主进程仍持续执行并最终以退出状态码0结束,不符合“进程应返回对应错误码”的常规逻辑,需分析原因。
环境信息
strace -- version 5.18 kernel -- 5.18.15-1.el8.elrepo.x86_64
相关strace输出
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7, si_uid=20000, si_status=0, si_utime=0, si_stime=0} --- strace: Process 2744190 attached [pid 2744190] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} --- strace: Process 2744191 attached strace: Process 2744192 attached strace: Process 2744193 attached strace: Process 2744194 attached strace: Process 2744195 attached strace: Process 2744196 attached strace: Process 2744197 attached strace: Process 2744198 attached [pid 2744196] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131d00} --- [pid 2744190] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xc} --- [pid 2744195] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131b80} --- strace: Process 2744248 attached strace: Process 2744249 attached strace: Process 2744250 attached [pid 2744190] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131a80} --- strace: Process 2744277 attached strace: Process 2744278 attached strace: Process 2744279 attached [pid 2744279] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xc} --- strace: Process 2744280 attached [pid 2744280] +++ exited with 0 +++ strace: Process 2744281 attached [pid 2744196] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131d00} --- [pid 2744279] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131c00} --- [pid 2744279] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131c00} --- [pid 2744196] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fa89a131d00} --- strace: Process 2744445 attached [pid 2744445] +++ exited with 0 +++ strace: Process 2744446 attached [pid 2744446] +++ exited with 0 +++ [pid 2744198] +++ exited with 0 +++ [pid 2744191] +++ exited with 0 +++ [pid 2744190] +++ exited with 0 +++ [pid 2744281] +++ exited with 0 +++ [pid 2744277] +++ exited with 0 +++ [pid 2744249] +++ exited with 0 +++ [pid 2744279] +++ exited with 0 +++ [pid 2744278] +++ exited with 0 +++ [pid 2744250] +++ exited with 0 +++ [pid 2744248] +++ exited with 0 +++ [pid 2744197] +++ exited with 0 +++ [pid 2744196] +++ exited with 0 +++ [pid 2744195] +++ exited with 0 +++ [pid 2744194] +++ exited with 0 +++ [pid 2744193] +++ exited with 0 +++ [pid 2744192] +++ exited with 0 +++ +++ exited with 0 +++
核心原因分析
- 自定义SIGSEGV信号处理函数:程序通过
sigaction()等系统调用注册了自定义的SIGSEGV处理逻辑。当线程触发段错误时,系统会调用该处理函数而非直接终止进程。处理函数可能完成了错误修复(比如动态映射缺失的内存区域、修正非法指针),让线程继续执行;或者触发线程的优雅退出流程,不影响主进程的正常运行。 - 线程级错误隔离:SIGSEGV信号默认作用于触发它的线程而非整个进程。如果信号处理函数没有终止整个进程,仅让出错线程退出(从strace输出可见,所有触发SIGSEGV的线程最终都以状态码0退出),主进程的主线程会继续执行,等待所有子线程结束后正常退出,返回状态码0。
- 特定业务逻辑触发的“预期内段错误”:部分程序(比如内存调试工具、动态加载框架)会故意触发SIGSEGV来实现特定功能,比如检测内存边界、延迟加载代码/数据。这类场景下,段错误是预期内的流程,程序会在信号处理函数中完成相应逻辑后恢复执行或正常退出。
- SIGSEGV类型与处理适配:输出中存在两种SIGSEGV类型:
SEGV_MAPERR(访问未映射内存)和SEGV_ACCERR(访问已映射但无权限内存),程序可能针对这两种场景分别做了处理,确保错误被局限在单个线程内,不扩散到整个进程。
内容的提问来源于stack exchange,提问作者Uruk-hai
相关产品推荐
相关产品推荐

