不是问题的问题:【undefined symbol: _tsrm_ls_cache in Unknown on line 0】

12 篇文章 0 订阅
10 篇文章 0 订阅
问题描述

我在服务器搭建了一个php运行环境(php-fpm),刚开始编译PHP的时候没有编译pdo_mysql模块,后面用动态加载模块的方式去加载pdo_mysql发现需要依赖mysqlnd,但是在编译好mysqlnd后,启动php-fpm发现如下提示信息:

PHP Startup: Unable to load dynamic library ‘/usr/local/PHP/lib/php/extensions/no-debug-zts-20160303/mysqlnd.so’ - /usr/local/PHP/lib/php/extensions/no-debug-zts-20160303/mysqlnd.so: undefined symbol: _tsrm_ls_cache in Unknown on line 0


环境介绍
  • 操作系统: centos-release-7-3.1611.el7.centos.x86_64
  • Apache httpd: Apache/2.4.43 (Unix), 安装在了/usr/httpd/
  • PHP: PHP 7.4.5
解决方案

我这里直接交代了,原因我也是猜的,在生成mysqlnd.so的时候,编译虽然通过,但是在执行时无法在当前指定的库中无法找到某些方法和定义。

重新编译PHP,此时指定编译mysqlnd和pdo_mysql。

./configure --prefix=/usr/local/php7.4.5/ --enable-fpm --with-apxs2=/usr/httpd/bin/apxs --with-zlib-dir=/usr/lib64 --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

编译PHP的时候直接加上--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd,让它在一开始就编译到PHP里面来,作为一个静态模块。

在php安装目录运行php -m,发现pdo-mysql和mysqlnd已经加载好了
在这里插入图片描述


一些思考和尝试

其实最理想的解决方式还是找到缺失的部分,是mysqlnd.so模块能动态添加成功,上面只是换了个路子走,避免了这个问题而已,并不算解决。下面只是我记录当时解决过程,看下有没有老师能够有兴趣解答下。

  • 【思考1】
    • _tsrm_ls_cache,其中TSRM模块是关于线程安全的,而且mysqlnd.so存放的目录是no-debug-zts-20160303,里面有个zts,证明我这个模块是以线程安全的模式编译的代码,相比线程不安全的模式,代码上肯定会多一些线程安全的操作,_tsrm_ls_cache应该就是线程安全相关的变量或者函数。
    • 我能不能换成线程不安全的模式呢(我本身是以php-fpm的模式启动php模块),但是我在网上查了半天,都再说编译PHP的版本的时候加上--enable-maintainer-zts参数使其变为线程安全,但是没有告诉我怎么使其变为线程不安全版本(默认不加好像也是线程安全,这里我很费解了,包我是在官网下载的wget https://www.php.net/distributions/php-7.4.5.tar.gz)。甚至我都加了--disable-maintainer-zts,但是最终的结果还是线程安全版本。
    • 这个我折腾半天,越搞越没有谱,于是放弃尝试,还是坚持用线程安全版本。
  • 【思考2】
    • 在根目录全局查找_tsrm_ls_cachefind / -type f -name "*.h" | xargs grep "_tsrm_ls_cache",发现
      /usr/local/php7.4.5/php-7.1.31/TSRM/TSRM.h:#define TSRMLS_CACHE _tsrm_ls_cache
      /usr/local/php7.4.5/include/php/TSRM/TSRM.h:#define TSRMLS_CACHE _tsrm_ls_cache

      这2个文件夹都有,第一个是下载的源码,第二个是编译后的,现在就是需要知道是在哪里引入的呢?在这里插入图片描述

    • 先进入/usr/local/php7.4.5/php-7.4.5/ext/mysqlnd/的文件夹,看它的MakeFile,发现include有去/usr/local/php7.4.5/include/php/TSRM寻找头文件,但是我没有看出来在哪里指定寻找库文件(makefile只懂一点点)。

    • 进入/usr/local/php7.4.5/include/php/TSRM/,查看TSRM.h文件

      /* Only compile multi-threading functions if we're in ZTS mode *
      #ifdef ZTS
      省略
      #define TSRMLS_CACHE _tsrm_ls_cache
      #else /* non ZTS */
      省略
      #define TSRMLS_CACHE
      省略
      #endif /* ZTS */
      

      这里定义了_tsrm_ls_cache,但是makefile在哪里去找库文件的实现,这些我就找不到了(水平有限,后期好好学习下C后再来看这个问题吧)。

总结

到此问题虽然规避了,但是仍然有很多问题暂时还不知道如何去排查。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值