问题背景
-
一开始问题是一台30的服务器上面编译出来的libxxxxxxxxx.so,启动时必core。经过验证后发现,只有在该服务器上编译生成的so,替换成正式集成服务中编译的libxxxxxxxxx.so就不会有问题。core堆栈如下图:
-
第二天,在一台51的服务器上面也出现了类似的core问题。core堆栈大体一样:
问题分析
-
一开始,有点怀疑是libmysqlclient.so不对导致的,于是将编译链接的libmysqlclient.so替成和集成环境一致的so版本还是会core。
-
分析Makefile后发现,发现在编译ARM、SUSE的时候用的是相对路径下的so、头文件,编译Linux下用的是系统路径下的so、头文件。其中so已经替换过无法解决问题,于是比对下头文件发现头文件版本不一样。
系统路径/usr/lib64/mysql/mysql_version.h:
相对路径…/mysql/include/mysql_version.h
结论
- 编译libxxxxxxxxx.so的时候,依赖的libmysqlclient.so和运行时的libmysqlclient.so不是同一个版本。
- 编译libxxxxxxxxx.so的时候,依赖的mysql头文件和运行时的libmysqlclient.so不是同一个版本。
附:动态库链接相关介绍
1. GCC链接时搜索直接依赖库的先后顺序
- LDFLAGS选项 -L 参数指定的路径。
- 系统环境变量 LIBRARY_PATH(某些系统或编译器下可能无效)。
- gcc安装时自身配置的搜索路径,gcc --print-search-dir | grep libraries 可查看,一般会包含该版本gcc必需的库而不一定包含当前系统库路径,链接时会以-L参数形式传递给ld。(一般都包含/usr/、/usr/lib/、/usr/lib64/)
- ld安装时自身配置的搜索路径,ld -verbose | grep SEARCH_DIR 可查看,gcc通过调用collect2工具调用ld。
2.运行时库的搜索库先后顺序
- 在编译目标代码时指定该程序的动态库搜索路径:通过gcc 的参数"-Wl,-rpath,“指定。当指定多个动态库搜索路径时,路径之间用冒号”:“分隔。
- 编译时LDFLAGS选项 -L 参数指定的路径。
- 系统环境变量LD_LIBRARY_PATH。
- 在 /etc/ld.so.conf.d/ 目录下的配置文件指定的动态库绝对路径(通过ldconfig生效,一般是非root用户时使用)。
- gcc安装时自身配置的搜索路径,gcc --print-search-dir | grep libraries 可查看,一般会包含该版本gcc必需的库而不一定包含当前系统库路径。
附录的参考链接:https://blog.csdn.net/csq_year/article/details/80146760