RHEL9/glibc2.34下valgrind --tool=massif在pthread_cond_timedwait触发SIGTRAP崩溃
Valgrind Massif工具在RHEL9+5.x内核环境下触发pthread_cond_timedwait SIGTRAP崩溃问题
我们在RHEL 9(glibc 2.34、Valgrind 3.22.0)环境下,使用valgrind --tool=massif运行多线程C应用时,发现程序在pthread_cond_timedwait处因SIGTRAP崩溃。进程无Valgrind错误信息,仅输出标准头部日志:
==611== Massif, a heap profiler ==611== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info ==611== Command: ./myapp
崩溃发生在定时器线程的内部循环中,相关代码如下:
struct timespec timeout; clock_gettime(CLOCK_MONOTONIC, &curtime); // ... 计算绝对超时时间 ... pthread_cond_timedwait(&cond, &mutex, &timeout); // <-- SIGTRAP触发点
注:条件变量已通过pthread_condattr_setclock初始化为CLOCK_MONOTONIC。
已观察到的现象:
- 在Kubernetes Pod(主机内核5.x,RHEL9容器)中可稳定复现该崩溃
- 在运行相同RHEL9容器镜像和二进制文件的4.18内核裸机主机上从未复现
- 测试环境使用相同的Valgrind 3.22.0、glibc 2.34和应用二进制文件
- 在4.18主机上使用
--trace-redir=yes运行时,未发现pthread_cond_timedwait的任何重定向注册记录 - 未设置
LD_PRELOAD环境变量;/etc/ld.so.preload文件为空
我们的假设:
Valgrind的函数重定向机制会在任何加载的客席库中查找带有_vgr/_vgw前缀的ZZ编码符号,找到后会用int3指令修补函数入口点。我们怀疑在较新的5.x内核上,某些因素导致Valgrind在--tool=massif模式下错误地为pthread_cond_timedwait注册了重定向,导致INT3触发时没有对应的有效处理程序,进而引发未处理的SIGTRAP信号。
已尝试的解决方法:
我们尝试将pthread_cond_timedwait替换为sem_timedwait(使用CLOCK_REALTIME,手动在调用前后释放/重新获取互斥锁)。但注意到vgpreload_drd-amd64-linux.so中也包含sem_timedwait的_vgw包装符号,如果根本原因是DRD预加载库被意外加载为客席库,那么这个替换方案可能不是真正的解决办法。
问题:
- Valgrind 3.22.0在较新内核上使用
--tool=massif(而非--tool=drd或--tool=helgrind)时,是否会向pthread_cond_timedwait注入INT3指令? - 是否存在已知的内核版本与Valgrind重定向扫描的交互问题,可以解释为何仅在Linux内核5.x上出现此问题?
- 是否有Valgrind选项或抑制规则可以避免这个问题?
内容的提问来源于stack exchange,提问作者Yaakov Goldsmith
相关产品推荐
相关产品推荐

