LD_PRELOAD对PHP extension失效的原因

最近写了一个主机健康检测和软负载均衡用的软件ZFOR(http://github.com/chaoslawful/zfor ),可以通过LD_PRELOAD预载入的方式拦截系统的域名解析调用(gethostbyname、getaddrinfo等)。但发现对某些发行版的PHP CURL extension光加载zfor动态库没有用,还必须同时加载libcurl.so才能生效。

 

经过一番搜索,发现原来是PHP编译时让Zend引擎使用了RTLD_DEEPBIND标志来加载扩展,该标志的作用是约束动态符号解析的查找范围为载入的动态库及其依赖项,而不是从所有已加载项的符号表中寻找。PHP启用该选项的原意是避免同时加载多个具有共同依赖库的扩展时产生多版本符号解析冲突的问题,但在这里就影响了zfor的preload拦截过程。因为PHP CURL扩展只依赖libcurl.so而不依赖libzfor.so,故在不预加载libcurl.so时libzfor.so不会列入PHP CURL扩展符号解析的查找范围,这样在libzfor.so中定义的getaddrinfo别名自然无法生效。

 

在同时预加载libcurl.so和libzfor.so时,由于是系统的动态库加载器ld-linux.so按默认解析策略进行符号解析,故会将libcurl.so中引用的getaddrinfo符号解析到libzfor.so中提供的实现上,而由于动态库都是单实例加载的,这样当PHP CURL扩展被载入时,其依赖的libcurl.so就会用之前预加载的那个实例来解决,不需要再进行符号查找,也就不用受到RTLD_DEEPBIND标志的约束了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值