strace处理库链接错误用例一则
问题:
在某个suse环境下编译完php-5.4.41及memcached扩展后,执行php报错如下,且检查/var/log/php_error.log无错误输出。
# php -v
Floating point exception
在/var/log/messages
有如下输出,然而并没有什么卵用。
kernel: [31353122.745809] php[2231] trap divide error ip:7fcb7a2c165f sp:7fff010bc800 error:0 in ld-2.4.so[7fcb7a2b9000+1b000]
排查:
这种几乎没有任何有用输出的故障,难道我们就没办法治它了吗?让我们祭出本文的主角:strace
。
# strace php -v
...
省略了一大波输出,从最后看起。
open("/usr/local/lib/libmemcached.so.11", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 I\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1296470, ...}) = 0
mmap(NULL, 2292344, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f126ce7d000
madvise(0x7f126ce7d000, 2292344, MADV_SEQUENTIAL|0x1) = 0
mprotect(0x7f126ceac000, 2097152, PROT_NONE) = 0
mmap(0x7f126d0ac000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2f000) = 0x7f126d0ac000
close(3) = 0
--- SIGFPE (Floating point exception) @ 0 (0) ---
+++ killed by SIGFPE +++
Process 23188 detached
执行流程先是打开/usr/local/lib/libmemcached.so.11
,然后将其映射入虚拟内存,接着执行这个库的代码段,就在这时候收到了“Floating point exception”。
从上面的输出可以看出极大可能是memcached扩展模块出的问题了。尝试在/etc/php.ini中注释掉memcached后果然没有报错了,这就说明了问题出在memcached。
找了下之前编译php-5.4.25的文档,原来用的包是memcached-2.1,现在用的是memcache-2.2。
怀疑可能是包的兼容问题,于是拿2.1版本过来重新编译替换,但是依然是“Floating point exception”的报错。
回过头来想了下,是libmemcached.so这个动态库出的问题,memcached是加载该动态库的,应该是去找libmemcached的问题,而不是找memcached。
# ldd /usr/local/services/php/lib/php/extensions/no-debug-zts-20100525/memcached.so
linux-vdso.so.1 => (0x00007fff5d5ff000)
libmemcached.so.11 => /usr/local/lib/libmemcached.so.11 (0x00007f12bc4b3000)
以下省略
再在正常的suse环境(还在使用php-5.2.17)下strace php -v
,对应的输出是这样子的:
open("/usr/lib64/libmemcached.so.11", O_RDONLY) = 3
然后在这个问题环境中查看,也有这个文件,什么情况? 先分别查看下这两个库文件属于哪个包:
# rpm -qf /usr/lib64/libmemcached.so.11
libmemcached11-1.0.10-1.1
# rpm -qf /usr/local/lib/libmemcached.so.11
php_memcached-2.1.0-1
然后再看下源上面的包:
# zypper se libmemcached
Restoring system sources...
Parsing metadata for update...
Parsing metadata for SUSE10-SP4...
S | Catalog | Type | Name | Version | Arch
--+---------+---------+--------------------+------------+-------
i | update | package | libmemcached | 1.0.10-1.1 | x86_64
i | update | package | libmemcached-devel | 1.0.10-1.1 | x86_64
i | update | package | libmemcached11 | 1.0.10-1.1 | x86_64
i | update | package | libmemcachedutil2 | 1.0.10-1.1 | x86_64
看来libmemcached11的/usr/lib64/libmemcached.so.11
才是正房啊。那又是为什么/usr/local/lib/libmemcached.so.11
这个小妾排在了正房的前面呢?
看下/etc/ld.so.conf
:
# cat /etc/ld.so.conf
/usr/X11R6/lib64/Xaw3d
/usr/X11R6/lib64
/usr/X11R6/lib/Xaw3d
/usr/X11R6/lib
/usr/x86_64-suse-linux/lib
/usr/local/lib
/opt/kde3/lib
/opt/gnome/lib
/lib64
/lib
/usr/lib64
/usr/lib
/usr/local/lib64
以下省略
看来是这个原因了。
2个解决方法:
- 确认没有使用php_memcached后卸载该rpm包;
- 调整/etc/ld.so.conf的顺序后执行ldconfig重新生成ld.so.cache(不建议,可能会导致别的应用读错动态库)