记一次用lldb 分析zan框架mac下连续coredump的bug

zanphp框架与zan扩展 官网:http://zanphp.io/
这里顺便提下zan框架最近努力在内外版本保持一致,其实框架本身代码是一致的,只不过围绕着soa架构有一些内部的系统,如log、调用链、服务注册与发现等需要剥离出去或者能够拿出来一个统一标准化的方案。
回归正题,
在ConnectionInitiator类中我们可以看到链接池相关的代码

  private function initPool($factoryType, $config)
    {
        if (PoolEx::support($factoryType)) {
            ....省略...
            $connectionPool = new PoolEx($factoryType, $config);
        } else {
           ....省略...
            $connectionPool = new Pool($factory, $config, $factoryType);
        }
        ConnectionManager::getInstance()->addPool($config['pool']['pool_name'], $connectionPool);
        
    }
    //PoolEx::support的定义
   public static function support($factoryType)
    {
        return class_exists("swoole_connpool") && in_array($factoryType, static::$engineMapEx, true);
    }

之前连接池是基于swoole内置方法来做的比如SwooleRedis、swoole_mysql等,如果安装了zan扩展,会通过PoolEx类走zan扩展的swoole_connpool类统一创建,现在zan扩展的连接池还处于未稳定版本,在mac环境下启动运行时出现了连续cordump的现象,如下图所示:

一开始用排除法定位到了如果zanphp redis 连接池配置文件maximum-connection-count不为0就触发,因为c调试的经验匮乏尤其是调试正在运行的进程,并且是mac下的lldb,请教了谢双大哥才把堆栈信息弄出来,因为swoole启动时会创建master进程、mannger进程和worker进程,而发生错误的是worker子进程,所以当你用lldb去attach(process attach –pid 2650)的时候是不行的,还没attach住就发生了错误。

那怎么办呢?办法是需要一个lldb先attach住mannger进程 ,然后使用 b fork打断点,然后再另外启动一个lldb 执行
process attach –name /usr/local/bin/php –waitfor , LLDB支持—waitfor选项。这个选项告诉LLDB等待下一个名称为指定名称的程序出现,然后连接它。然后在第一个lldb 通过c命令(跳到下一个断点处)可以让程序继续运行,当发生coredump的时候,在第二个lldb 使用bt命令打印出了堆栈信息,遂分析出是调用redisAsyncDisconnect方法导致。图例:

第一个lldb
第二个lldb

可怎么拿到 mannger进程的id ?  ps axu | grep nova 我们可以看到启动后相关的所有进程,主进程先启动 之后启动mannger进程 随后一直创建worker进程,所以根据运行时间 运行时间第二的 就是,一看一个准。

发表评论

电子邮件地址不会被公开。 必填项已用*标注