从ldd谈起 [linux演习]
来源:互联网 发布:网络电视机顶盒哪个好 编辑:程序博客网 时间:2024/06/01 23:08
ldd的原理
ldd 命令可以打印出ELF Executable文件的动态链接库依赖.
如果了解ELF文件格式, 将非常容易理解系统连接器是如何加载so文件, 并链接启动一个ELF可执行文件的. 一句话来说: ldd命令的原理就是调用系统连接器, 修改连接器依赖的环境变量, 使得ELF加载时,让链接器输出具体需要哪些so文件, 由于linux上可执行文件为ELF格式, 所以ldd命令也就仅可以输出ELF文件的so依赖关系. 其他可执行文件格式, 比如a.out格式所的连接器同ELF文件连接器不同. 所以ldd命令无法处理a.out格式; 下面摘录了man ld.so的帮助信息, 其中列出了连接器以及连接器的用途. 可以看到ELF文件的链接器为/lib/ld-linux.so.1或者/lib/ld-linux.so.2 这里的1和2对应对应libc1和libc2两个c语言库. 而a.out格式则使用/lib/ld.so作为程序启动时加载动态so文件的链接器.
/lib/ld.so a.out dynamic linker/loader /lib/ld-linux.so.{1,2} ELF dynamic linker/loader /etc/ld.so.cache File containing a compiled list of directories in which to search for libraries and an ordered list of candidate libraries. /etc/ld.so.preload File containing a whitespace separated list of ELF shared libraries to be loaded before the program. lib*.so* shared libraries
正是基于以上原理, 我们其实可以非常简单的猜想到ldd命令的内部逻辑, 它只是简单校验命令行参数, 然后将参数最后传递给ld-linux.so文件, 利用链接器读取ELF文件中的so依赖关系而已. 所以在系统中ldd命令真的只是一个shell脚本, 不要惊讶于一个shell脚本有这样强大的功能, 这个脚本只是编译工具,链接工具某一个简单阶段的接口调用而已. 想真正的去了解连接器是如何工作的. 推荐各位仔细研读ELF文件格式. 明白了可读的文本最终如何被编译链接, 并加载启动的流程之后, 所有东西最终都无比明白.
顺便扯远一点: 一切知识最终都是历史, ELF文件格式也是这样. a.out提出之后, unix和DOS分裂之后, linux出现之后..gcc, gdb, 链接器..这些东西最后都植根与ELF文件格式, 这些工具一些生成ELF文件, 另外一些则读取其中一部分内容而已...二进制和操作系统的秘密都藏在ELF和ld-linux.so文件之后.
回到ldd的话题, 由于ELF展开之后实在内容太多, 我们还是专注于ldd周边工具. 与ldd命令类似的 链接器接周边工具, 还有ldconfig。
纵观ldd脚本的内容, 可以发现整个脚本除了基本参数校验之外, 唯一功能即设置变量LD_TRACE_LOADED_OBJECTS=1. 链接器工作时如果该变量有值,则输出动态跨信息。
add_env="LD_TRACE_LOADED_OBJECTS=1 LD_WARN=$warn LD_BIND_NOW=$bind_now"add_env="$add_env LD_LIBRARY_VERSION=\$verify_out"add_env="$add_env LD_VERBOSE=$verbose"if test "$unused" = yes; then add_env="$add_env LD_DEBUG=\"$LD_DEBUG${LD_DEBUG:+,}unused\""fi# The following use of cat is needed to make ldd work in SELinux# environments where the executed program might not have permissions# to write to the console/tty. But only bash 3.x supports the pipefail# option, and we don't bother to handle the case for older bash versions.if set -o pipefail 2> /dev/null; then try_trace() { eval $add_env '"$@"' | cat }else try_trace() { eval $add_env '"$@"' }fi
一个简单的模仿: 自己export LD_TRACE_LOADED_OBJECTS=1, 然后运行ls命令。。。
0 0
- 从ldd谈起 [linux演习]
- [linux device driver] Chapter03:从kmalloc谈起
- Linux-ldd
- linux :ldd
- 【演习】
- 从LDD入门
- 李开复:从诚信谈起
- 从程序员创业谈起
- 从西游记谈起
- 从《人件》谈起
- 从Juqery-UI谈起
- 从“煮酒论英雄”谈起
- 从PipedInputStream/PipedOutputStream谈起
- 从ArcGIS Online谈起
- 从“最后一公里”问题谈起
- 从SaaS缺点谈起
- 从PipedInputStream/PipedOutputStream谈起
- 从strlen谈起
- windows下php的版本如何选择?
- 【模拟】 HDOJ 5071 Chat
- 马云:初次创业时我连计算机是什么都不知道
- 通过XML签名和加密更安全地交换数据
- 【安卓病毒分析报告】FakeBank-盗取韩国银行信息的手机病毒
- 从ldd谈起 [linux演习]
- vs2010 sp1 创建silverlight 时,提示我 “在创建silverlight项目之前,您需要安装最新的silverlight Developer运行时
- C# asp中,如何把二进制图片流转换成图片,并显示在网页上的一些注意事项
- IE前端CSS处理小结(demo下载)
- 2014 语录
- nginx 架构
- 解决vmware 和hyper-v不能共存的问题
- 关于 debug能过而release编译不过的问题
- 第9周项目1-利用循环求和