0

0

strace -p 挂上后卡在 futex_wait 或 poll 的锁等待深挖方法

冰川箭仙

冰川箭仙

发布时间:2026-01-20 16:38:01

|

760人浏览过

|

来源于php中文网

原创

strace -p 显示卡在 futex_wait 或 poll 表明进程正阻塞于内核态等待同步事件或 I/O 就绪,需通过 ps、/proc/PID/stack、gdb、lsof 等工具定位等待原因、持有者及死锁链。

strace -p 挂上后卡在 futex_wait 或 poll 的锁等待深挖方法

strace -p 挂上进程后卡在 futex_waitpoll,说明进程正阻塞在内核态等待某个同步事件(如互斥锁、条件变量、I/O 就绪等),此时 strace 本身不会卡住,但你看到的“卡”其实是进程真实处于睡眠状态。关键不是让 strace “继续”,而是定位它为何等、等什么、谁在控制这个等待。

确认是否真卡:区分挂起与正常阻塞

strace 显示停在 futex_waitpoll 是常见且正常的——这表示系统调用尚未返回,进程被内核调度为 S(可中断睡眠)或 D(不可中断睡眠)状态。

  • ps -o pid,ppid,comm,wchan,state -p PID 查看当前等待的内核函数(wchan)和状态:
    • 若 wchanfutex_wait_queue_medo_futex,说明卡在 futex 上;
    • 若是 do_sys_pollep_poll,说明卡在 poll/epoll 等待 I/O;
    • 若 stateD(尤其是 futex 场景),需警惕死锁或资源耗尽(如信号量未释放、持有锁的线程已崩溃)。
  • cat /proc/PID/stack 查看内核(需 root),可确认具体等待路径,例如是否在 mutex_lock_slowpathfutex_wait,或 ep_pollwait_event_interruptible

深挖 futex_wait:定位锁持有者与死锁链

futex 等待本质是用户态加锁失败后陷入内核等待唤醒,真正线索在用户态锁状态和持有者线程。

甲骨文AI协同平台
甲骨文AI协同平台

专门用于甲骨文研究的革命性平台

下载
  • gdb -p PID 进入进程,执行:
    info threads 查看所有线程及状态;
    • 对每个线程执行 bt(尤其关注状态为 Blocked 或长时间停在 pthread_mutex_lock__lll_lock_wait 的线程);
    • 若有符号,可查 pthread_mutex_t 地址,用 print *(pthread_mutex_t*)0xADDR__owner 字段(持有线程 tid)。
  • 若无调试符号,可用 pstack PID 快速抓全部线程用户栈(等价于 gdb + bt 所有线程);结合 /proc/PID/mapsreadelf -S 可尝试定位锁变量内存位置。
  • 检查是否发生死锁:多个线程互相等待对方持有的 mutex/condvar,典型表现为 A 等 B 持有的锁,B 等 C 持有的锁,C 又等 A 持有的锁 —— 此时需人工梳理锁获取顺序或用 lsof -p PID + ls /proc/PID/fd 辅助判断资源依赖。

深挖 poll 等待:厘清 I/O 事件源与就绪条件

poll/epoll/pselect 等调用卡住,说明指定的 fd 集合中没有任何一个满足触发条件(如可读、可写、异常)。问题往往出在事件源未就绪或 fd 被误关闭/重复使用。

  • lsof -p PIDls -la /proc/PID/fd/ 列出所有打开 fd,重点关注:
    • socket fd:看协议(TCP/UDP)、状态(ESTABLISHED、CLOSE_WAIT)、对端地址;
    • pipe/fifo:是否有读/写端关闭;
    • eventfd/timerfd:是否被正确 write/read;
    • epoll fd 本身:确认是否已通过 epoll_ctl 添加了目标 fd。
  • 结合 ss -tulnpnetstat -tulnp 检查监听端口、连接状态,确认对端是否存活、是否发送了数据;若等待的是本地 pipe/eventfd,用 strace -e trace=write,read -p PID 单独跟踪读写行为,看是否有 write 发生但未被 read 消费。
  • 注意超时值:若 poll 第三个参数为 -1(无限等待),则必须有外部事件触发;若为 0(非阻塞),则不应卡住 —— 此时卡住大概率是 strace 误判或进程实际卡在其他地方(如信号处理中被暂停)。

辅助诊断与规避技巧

有些场景下 strace 自身会干扰行为(如信号屏蔽、时间戳精度),或难以持续观察,需配合其他工具

  • perf record -e 'syscalls:sys_enter_futex,syscalls:sys_enter_poll' -p PID 抓取系统调用入口,再用 perf script 分析调用上下文和参数(如 futex 的 uaddr、op、val)。
  • 对多线程程序,优先用 strace -f -p PID 跟踪所有线程,避免只盯主线程而错过持有锁的子线程。
  • 若进程对 strace 敏感(如反调试、自修改代码),改用 gdb 附加后设置断点:
    break syscall 或具体函数如 pthread_mutex_lock
    catch syscall futex 监控 futex 调用细节(需内核支持)。
  • 生成 core dump(gcore PID)后离线分析,避免线上反复附加影响服务。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

185

2023.09.27

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

118

2025.10.15

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

256

2025.10.24

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.7万人学习

Vue 教程
Vue 教程

共42课时 | 6.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号