linux 关于动态库的知识
问题起缘于编译一个程序时,使用glib2-2.28.8的动态库,而系统自带的是glib2-2.22.5
不想升级系统的glib2库,而使用程序自带库文件的方式加载(类似windows系统,优先加载当前目录的DLL文件)。
1.首先编译时,使用-L指定lib路径,-lglib-2.0指定库文件名
2.运行时通过,LD_LIBRARY_PATH=./ 指定搜索当前目录为库目录
3.测试发现使用的是系统的库
ldd ./test
linux-vdso.so.1 => (0x00007fff86fff000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f386e16c000)
libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f386df68000)
libz.so.1 => /lib64/libz.so.1 (0x00007f386dd52000)
libc.so.6 => /lib64/libc.so.6 (0x00007f386d9bf000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f386d7bb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f386e45f000)
失败,怀疑是LD_LIBRARY_PATH指定的库路径,处于搜索路径的队列尾部,造成优先找到系统的库,那么可不可以通过修改“链接的库文件名”,达到目的了
1.修改libglib-2.0.so文件为libmyglib.so,链接时使用-lmyglib指定链接库
2.运行时通过,LD_LIBRARY_PATH=./ 指定搜索当前目录为库目录
3.测试发现我定义的库居然没有出现,而且还使用来系统的GLIB2库
ldd ./test
linux-vdso.so.1 => (0x00007fff86fff000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f386e16c000)
libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f386df68000)
libz.so.1 => /lib64/libz.so.1 (0x00007f386dd52000)
libc.so.6 => /lib64/libc.so.6 (0x00007f386d9bf000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f386d7bb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f386e45f000)
查询资料后发现,“对于动态库,实际链接发生在运行时而不是编译和链接时”,好吧,我理解。
那么编译的时候,难道没有把程序要使用到的动态库文件名称,记录到程序内部??
就像WINDOWS下,缺少某个DLL,程序会提示缺少DLL文件的文件名。
于是又查询资料发现 “生成可执行文件时,如果链接的是静态库,那么链接器会按照静态链接规则,将对应的符号引用进行重定位。而如果是动态库,链接器会将这个符号标记为动态链接的符号,不进行重定位,而是在装载时再进行。所以,尽管是动态链接,如果是已经进入到了链接阶段,那么也需要能在相应的.so中找到某符号的定义,否则也会引发Undefined reference to的链接错误。因为链接器只有通过.so文件,才能判断某符号是个动态链接符号,所以也需要读取这些.so文件,找到相应符号的定义”
意思就是,连接器只是做确认函数符号可用,就编译通过来,更本没记录动态库的文件名,这点和WINDOWS不一样
而实际运行装载的时候,只通过函数符号,装载需要的.SO就可以来,索引我定义的libmyglib.so又被没有机会装载进来,被系统的替代了。
知道问题原因,解决方法有2个
1.解决加载顺序的问题,LD_PRELOAD可以实现
LD_LIBRARY_PATH 将其他目录加入库搜索路径。它的内容应该是由冒号
分隔的目录列表,与可执行文件的 PATH 变量具有相同的格式。
如果调用设置用户 ID 或者进程 ID 的程序,该变量被忽略。
LD_PRELOAD 首先装入用户定义的库,使得它们有机会覆盖或者重新定义标准库。
export LD_PRELOAD=./libglib.so:./libgmodule.so
ldd ./test
linux-vdso.so.1 => (0x00007fffc31ff000)
./libglib.so (0x00007ffa5d757000)
./libgmodule.so (0x00007ffa5d553000)
libz.so.1 => /lib64/libz.so.1 (0x00007ffa5d330000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffa5cf9d000)
librt.so.1 => /lib64/librt.so.1 (0x00007ffa5cd95000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007ffa5cb91000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffa5da6e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffa5c974000)
2.替换系统的glib2库,有三种方式,最好使用第一种,其他方式会遗留垃圾
2.1升级安装覆盖
2.2直接拷贝.so覆盖,或更改libglib-2.0.so.0链接的指向
2.3共享当前版本的库的系统 sudo ldconfig /opt/glib-2.28.8/lib
ldd ../bin/test
linux-vdso.so.1 => (0x00007fff897ff000)
libglib-2.0.so.0 => /opt/glib-2.28.8/lib/libglib-2.0.so.0 (0x00007f59f5f02000)
libgmodule-2.0.so.0 => /opt/glib-2.28.8/lib/libgmodule-2.0.so.0 (0x00007f59f5cfe000)
libz.so.1 => /lib64/libz.so.1 (0x00007f59f5ae8000)
libc.so.6 => /lib64/libc.so.6 (0x00007f59f5755000)
librt.so.1 => /lib64/librt.so.1 (0x00007f59f554d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f59f5349000)
/lib64/ld-linux-x86-64.so.2 (0x00007f59f6226000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f59f512c000)
LD_DEBUG通过设置这个环境变量,可以方便的看到 loader 的加载过程(包括库的加载,符号解析等过程),使用【LD_DEBUG=help 可执行文件路径】可查看使用帮助。
LD_PRELOAD环境变量指定的共享库会被预先加载,如果出现重名的函数,预先加载的函数将会被调用,如在预先加载的库中包含自定义的puts函数,则在执行程序时将使用自定义版本的puts函数,而不是libc库中的puts函数。
列出链接符号
nm -Du /lib64/libglib-2.0.so.0
linux 关于动态库的知识的更多相关文章
- 谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH
谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.ph ...
- Linux下动态库生成和使用
Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...
- Linux生成动态库系统
Linux生成动态库系统 一个.说明 Linux下动态库文件的扩展名为 ".so"(Shared Object). 依照约定,全部动态库文件名称的形式是libname.so(可能在 ...
- DELPHI开发LINUX的动态库
DELPHI开发LINUX的动态库 WINDOWS的动态库是.dll,这个大家都知道. LINUX也有动态库,扩展名是.so,现在DELPHI也能开发LINUX的动态库哦. DELPHI对LINUX的 ...
- 深入理解LINUX下动态库链接器/加载器ld-linux.so.2
[ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...
- linux常用命令及一些静态动态库相关知识
1 查找然后grep,最后在复制到特定目录 find . -depth -name *.java | xargs grep -i lijiangtao | awk -F ":" ' ...
- Linux下动态库查找路径的问题
说到和动态库查找路径相关的问题,总体上可以分为两类: 第一类: 通过源代码编译程序时出现的找不到某个依赖包的问题,而如果此时你恰好已经按照它的要求确确实实.千真万确.天地良心地把依赖库给装好了, ...
- 【linux】linux下动态库so文件的一些认识
来源:http://mypyg.iteye.com/blog/845915 so其实就是shared object的意思.今天看了上面的博客,感觉好吃力.赶紧做个笔记记录一下.下面的内容大多都是连接中 ...
- LINUX下动态库及版本号控制
针对同一动态组件的不同版本链接和加载. 一.概念 DLL HELL字面意思是DLL"灾难",是由于com组件(动态库)升级引起的程序不能运行的情况 ...
随机推荐
- Oracle GoldenGate配置异构数据库数据传输(oracle到sqlserer)的dml操作(带pump进程)
实验环境:os01:Red Hat Enterprise Linux Server release 5.1 (32位)db01:oracle 10.2.0.1.0 os02:Windows 7 (32 ...
- SQL 数据库知识点回顾
SQL2008 一.安装注意事项: 1.修改用户权限(在一个安装页面中有七八个)(改成net.) 2.添加当前系统用户为账户 二.主键,约束,索引 三.增删改查: insert.delete.upda ...
- python正则表达式基础篇
1.正则表达式基础 1.1简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大 ...
- vc++ internet
1.用VC开发ActiveX文档服务器 MFC 4.2不支持开发ActiveX容器,但支持ActiveX服务器.只要在使用MFC AppWizard生成应用程序框架时选择支持Active Docume ...
- html5 canvas 画hello ketty
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- 解决jquery zclip 插件点击无效的问题
使用jquery zclip 用于页面复制文本内容. 首先引入js <script type="text/javascript" src="../js/jquery ...
- jupyter巨好玩-常用设置
整理一下有用的设置: 自定义ipython工作目录 用jupyter notebook默认打开的页面时,默认在的是home路径,会看见一大堆东西,假如我们只想展示jupyter的工程目录咋办? 简单说 ...
- (极简)linux安装QT4.7.3
1.下载QT http://download.qt.io/ 我用的:qt-everywhere-opensource-src-4.7.3.tar.gz 2.解压安装QT 建议解压到/use/local ...
- GDI+简单现实文字旋转
原文 http://www.cnblogs.com/kaixiangbb/p/3301272.html 题记 入职新公司已快有两月了,试用期已快结束,项目却迟迟还未正式启动.安排给我的多是些琐事,一直 ...
- css案例学习之id要唯一
ID有两个的后果 <html> <head> <title>ID选择器</title> <style type="text/css&qu ...