Workerman worker 退出状态 139 怎么办?SIGSEGV 段错误终极排查指南
在 Workerman 或 webman 项目中,经常会遇到 worker 进程反复退出,日志显示类似:
worker[none:21319] exit with status 139

这个 139 退出码是 Linux 系统下最典型的崩溃信号之一。它等于 128 + 11,其中:
- 128 表示进程被信号杀死;
- 11 对应 SIGSEGV(Segmentation fault,段错误)。
段错误几乎总是因为进程访问了不属于自己的内存导致的,比如:
- 空指针解引用(null pointer dereference);
- 已释放内存继续使用;
- 数组越界;
- 写入了只读内存区域。
在 PHP + Workerman/webman 的常驻内存模型下,这种崩溃通常不是你的业务代码逻辑错误,而是底层 C 扩展或 PHP 本身的 bug 引发的,尤其当使用了不稳定/旧版本的扩展时。
常见扩展排行(基于大量真实案例)
- amqp 扩展(RabbitMQ 客户端)—— 概率最高
老版本(如 < 2.2.0)在连接断开、重连、channel 关闭或错误处理路径下,容易出现connection_resource = 0x0(空指针)后仍被解引用,导致 SIGSEGV。典型 gdb 栈指向php_amqp_error_advanced()函数。 - opcache(尤其是开启 JIT)
PHP 8.1/8.2 早期版本 + JIT 在复杂闭包、回调或异常场景下偶发段错误。 swoole / openswoole老版本
协程 bug 或与特定 PHP 版本不兼容。redis / mongodb / memcached等持久连接扩展
高并发下连接异常时偶发内存损坏。- PHP 本身的小版本 bug
如某些 8.1.x、8.2.x 在资源管理或异常抛出时的崩溃。
推荐排查流程(99% 案例可定位)
步骤 1:快速验证
在 php.ini(或 cli 专用配置文件,如/etc/php/8.x/cli/conf.d/)中注释掉最可疑的项,重启服务观察:
; 关闭 opcache(尤其是 JIT,最常见临时解法) ;[opcache] ;opcache.enable=1 ;opcache.enable_cli=1 ;opcache.jit=tracing ; 或任何 jit 值 ; 注释常见问题扩展 ;extension=amqp ;extension=redis ;extension=swoole ;extension=mongodb
重启命令:
php start.php restart -d
- 如果 139 消失 → 逐个放开注释,定位罪魁祸首。
- 如果仍崩 → 进入核心转储分析。
步骤 2:开启 core dump + gdb 精确定位
这是官方和社区公认的最有效方法,能直接看到崩溃发生在哪个扩展的哪一行。
- 临时开启 core dump(当前 shell 有效):
ulimit -c unlimited
- 设置 core 文件路径(建议放项目根目录,避免权限问题):
mkdir -p ./core_dump echo "./core_dump/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
- 等待下一次崩溃,core 文件自动生成,然后用 gdb 分析 (提前安装 gdb),例如:
./core_dump/core-webman-3646384-1769570816 或 core-webman-xxx-xxx
- 用 gdb 分析(需提前 sudo apt install gdb):
gdb /usr/bin/php ./core_dump/core-webman-3646384-1769570816

典型输出示例(amqp 导致的真实案例):

Program received signal SIGSEGV, Segmentation fault. php_amqp_error_advanced (reply=..., message=0x7ffff5118b80 <amqp_globals>, connection_resource=0x0, channel_resource=channel_resource@entry=0x7fffef6dbe10, fail_on_errors=fail_on_errors@entry=1) at /tmp/pear/temp/amqp/amqp.c:449 449 /tmp/pear/temp/amqp/amqp.c: No such file or directory. (gdb) bt #0 php_amqp_error_advanced (reply=..., message=0x7ffff5118b80 <amqp_globals>, connection_resource=0x0, channel_resource=channel_resource@entry=0x7fffef6dbe10, fail_on_errors=fail_on_errors@entry=1) at /tmp/pear/temp/amqp/amqp.c:449 #1 0x00007ffff50f57fa in php_amqp_error (reply=..., message=<optimized out>, connection_resource=<optimized out>, channel_resource=channel_resource@entry=0x7fffef6dbe10) at /tmp/pear/temp/amqp/amqp.c:413
看到 amqp 相关函数 + connection_resource=0x0 → 关闭通道时出现段错误。基本锁定 amqp 扩展。
php-amqp version: 2.1.2 (also tried 2.1.2) PHP version: 8.4.14 librabbitmq version: 0.11.0 RabbitMQ server version: 3.8.9
步骤 3:针对性修复
检查当前版本:
php -r "echo phpversion('amqp');"
升级到 2.2.0 或最新(2.2.0 修复了connection_resource空指针相关 bug):
sudo pecl uninstall amqp sudo apt install -y librabbitmq-dev php-dev sudo pecl install amqp-2.2.0 # 或 sudo pecl install amqp 拉最新
重启 webman 后验证。
“php-amqp v2.2.0 修复清单(Release Notes)
这是最关键的修复:在内部错误检查宏(PHP_AMQP_MAYBE_ERROR)中显式传入 connection_resource 参数,加强了对连接资源的检查和防护,避免空指针(connection_resource = 0x0)解引用导致的 SIGSEGV 崩溃(常见于错误处理路径,如你的 gdb 栈中 amqp.c:449)。

v2.2.0 针对你遇到的 “connection_resource=0x0 空指针崩溃”做了直接修复(通过在错误宏中传递 connection_resource 参数加防护),同时提升了对 PHP 8.4/8.5 的支持和构建安全性。升级后稳定性显著提高,尤其适合 Workerman/webman + RabbitMQ 的长连接场景。
预防与监控建议
- 生产环境定期
pecl upgrade所有扩展。 - 关闭
opcache JIT或用tracing模式。 - 用脚本监控日志中的 “exit with status 139”,自动告警 + 保存 core 文件。
- 避免实验性 PHP/扩展版本。
遇到 139 别慌,99% 是扩展问题,不是你的代码写错了。按照上面流程,先关 opcache → 关 amqp 等扩展 → gdb 看栈 → 升级对应扩展,基本都能快速解决。
以上关于Workerman worker 退出状态 139 怎么办?SIGSEGV 段错误终极排查指南的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Workerman worker 退出状态 139 怎么办?SIGSEGV 段错误终极排查指南
微信
支付宝