GDB是定位Swoole Worker卡死、RSS暴涨、协程不退出的终极手段,需通过pgrep获取PID、解决ptrace权限、加载PHP/Swoole调试符号、用info proc mappings比对rwx段识别内存泄漏起点。

在宝塔面板中成功安装 Swoole 扩展后,若实际运行中出现 Worker 进程卡死、内存 RSS 持续上涨、协程不退出等现象,必须跳过日志和 PHP 层面排查,直接进入 C 运行时现场抓取与分析,否则永远无法定位真实阻塞点。
确认当前活跃的 Swoole Worker 进程 PID
执行 pgrep -f "php worker" 获取进程号;若返回为空,说明未启动 Swoole 服务或已崩溃,需先确保 php server.php 类启动脚本正在运行且未报错退出。
这一步不能依赖 ps aux | grep swoole,因为部分守护模式会隐藏关键词,pgrep -f 才能匹配完整命令行参数。
用 GDB attach 到目标进程并检查 ptrace 权限
执行 sudo gdb -p $(pgrep -f "php worker");若提示 ptrace: Operation not permitted,说明内核阻止了非子进程调试。
立即检查:cat /proc/sys/kernel/yama/ptrace_scope。若输出为 【1】,则必须临时放开:echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope。该操作无需重启,但仅对当前会话生效。
容器环境请跳过此步,改用 docker run --cap-add=SYS_PTRACE 启动,否则 gdb 将始终失败。
加载 PHP 调试符号并查看完整调用栈
进入 GDB 后,先确认是否加载了 PHP 源码级符号:
① 执行 source /www/server/php/80/src/.gdbinit(路径需替换为你实际编译 PHP 的源码目录);若提示 No such file,说明 PHP 是宝塔预编译版,不具备调试能力,必须重装源码版 PHP 并启用 --enable-debug。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
② 输入 zbacktrace;若仍显示大量 ?? 或只有 swServer_master_onAccept 等裸函数名,说明 Swoole 扩展也未带调试符号——此时需回到源码目录,用 ./configure --enable-debug 重新编译并 make install。
③ 正常输出应包含 PHP 用户函数名(如 onReceive、handleMessage)及完整参数,这是判断协程卡在哪个逻辑层的唯一依据。
快速识别内存泄漏源头
在 GDB 中执行:info proc mappings,然后退出:quit。
将输出保存为文件:gdb -p $(pgrep -f "php worker") -ex "info proc mappings" -ex "quit" > /tmp/memmap1.txt。
等待 RSS 上升至少 50MB 后,再执行一次,保存为 /tmp/memmap2.txt。
对比两次结果:grep rwx /tmp/memmap1.txt | wc -l 和 grep rwx /tmp/memmap2.txt | wc -l;若后者多出 3 段以上且地址连续递增,【新增段起始地址就是 malloc 未 free 的泄漏起点】。










