文档章节

ldd命令,查看依赖的动态库信息 nm命令可以列出一个函数库文件中的符号表

lieefu
 lieefu
发布于 2015/12/21 09:35
字数 1861
阅读 2362
收藏 3
点赞 0
评论 0

ldd命令的作用是查看程序依赖的动态链接库信息。使用nm命令也可以获取库函数的信息;nm命令可以列出一个函数库文件中的符号表,它对静态的库函数和共享的库函数都能起作用。

Linux动态库的默认搜索路径是/lib和/usr/lib。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及该动态库的其它资源了。在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定。
方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径
可以通过编辑配置文件/etc/ld.so.conf来指定动态库的搜索路径,该文件中每行为一个动态库搜索路径。每次编辑完该文件后,都必须运行命令ldconfig使修改后的配置生效。我们通过例1来说明该方法。

方法二:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。下面通过例2来说明本方法。


方法三:在编译目标代码时指定该程序的动态库搜索路径
在编译目标代码时指定程序的动态库搜索路径。这是通过gcc 的参数"-Wl,-rpath,"指定。当指定多个动态库搜索路径时,路径之间用冒号":"分隔。


当链接某个程序时,在运行期您可以指定另外的搜索路径。在 gcc 中,其 语法是 -Wl,-R/path。如果程序已经被链接,那么您也可以设置环境变量 LD_LIBRARY_PATH 来改变这一行为。通常只是在应用程序需要搜索的路径 不是系统级默认路径的一部分时才需要这样做,对大部分 Linux 系统来说,这种情况很少见。 理论上,Mozilla 用户可以发布某个使用这个路径设置所编译的二进制程序,但是他们 更倾向于发布包装器(wrapper)脚本,在启动可执行程序之前正确地设置程序库路径。
设置程序库路径可以为两个应用程序需要同一程序库的不兼容版本的这种罕见情况提供一个迂回解决方案。可以使用包装器脚本使某一应用程序在使用特殊版本程序库的目录中进行搜索。这称不上是一个 完美的解决方案,但是在某些情况下,这是您能采用的最佳方法。
如果出于不得已的原因需要为很多程序添加某个路径,那么也可以修改系统的默认搜索路径。通过 /etc/ld.so.conf 控制动态链接器,该文件包含默认搜索路径的列表。 对 LD_LIBRARY_PATH 中指定的任何路径的搜索都要先于 ld.so.conf 中列出的路径,所以用户可以覆盖这些设置。
大部分用户没有理由修改系统默认程序库搜索路径;通常环境变量更适用于修改搜索路径,比如 连接某个工具包中的程序库,或者使用某个程序库的较新版本的测试程序。

ldd的作用是打印可执行档依赖的共享库文件。它是glibc的一部分,由Roland McGrath和Ulrich Drepper维护:
$ ldd --version
ldd (GNU libc) 2.9
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.


但是ldd本身不是一个程序,而仅是一个shell脚本:
$ which ldd
/usr/bin/ldd
$ file /usr/bin/ldd 
/usr/bin/ldd: Bourne-Again shell script text executable


ldd命令其实是依靠设置一些环境变量而实现的(也就是说ldd的作用只是设置一些环境变量的值)
如:LD_TRACE_LOADED_OBJECTS
只要设置其值非空即可。
$ export LD_TRACE_LOADED_OBJECTS=1
$ ls /usr
linux-gate.so.1 =>  (0xb7fac000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f93000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f79000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f70000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e0d000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7df4000)
/lib/ld-linux.so.2 (0xb7fad000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7df0000)
libattr.so.1 => /lib/libattr.so.1 (0xb7dea000)


撤销该环境变量,ls即又可以恢复正常使用:
$ unset LD_TRACE_LOADED_OBJECTS
$ ls  /usr/
bin  games  include  lib  lib32  lib64  local  sbin  share  src  X11R6


更多的环境变量:
1、LD_TRACE_LOADED_OBJECTS
2、LD_WARN
3、LD_BIND_NOW
4、LD_LIBRARY_VERSION
5、LD_VERBOSE
6、LD_DEBUG


ldd默认开启的环境变量是:LD_TRACE_LOADED_OBJECTS=1
其他的变量(和值)分别对应一些选项:
-d, --data-relocs -> LD_WARN=yes
-r, --function-relocs ->LD_WARN和LD_BIND_NOW=yes
-u, --unused -> LD_DEBUG="unused"
-v, --verbose -> LD_VERBOSE=yes
LD_TRACE_LOADED_OBJECTS为必要环境变量,其他视具体情况。


更为详细的命令选项(或者参看man、info):
$ ldd --help
Usage: ldd [OPTION]... FILE...
--help              print this help and exit
--version           print version information and exit
-d, --data-relocs       process data relocations
-r, --function-relocs   process data and function relocations
-u, --unused            print unused direct dependencies
-v, --verbose           print all information
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.


但是ldd命令的本质是执行了:/lib/ld-linux.so.* 
我们可以从以上的内容中(ls /usr中)发现:/lib/ld-linux.so.2 (0xb7fad000)。
$ ls -l /lib/ld-linux.so.* 
lrwxrwxrwx 1 root root 9 2009-09-05 22:54 /lib/ld-linux.so.2 -> ld-2.9.so
刚编译后的文件可能是:/lib/ld.so。如果是libc5则是/lib/ld-linux.so.1, 而glibc2应该是/lib/ld-linux.so.2。


$ /lib/ld-linux.so.2  --list /bin/ls
linux-gate.so.1 =>  (0xb8050000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb8037000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb801d000)
libacl.so.1 => /lib/libacl.so.1 (0xb8014000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eb1000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7e98000)
/lib/ld-linux.so.2 (0xb8051000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7e94000)
libattr.so.1 => /lib/libattr.so.1 (0xb7e8e000)
我们可以看到以上等同于ldd ls。/lib/ld-linux.so.2还有其他一些选项:
1、--verify 
2、--library-path PATH
3、--inhibit-rpath LIST


ldd可以获得的共享库文件,其实是通过读取ldconfig命令组建起来的文件(/etc/ld.so.cache)。
默认的共享库文件搜索/lib优先于/usr/lib,而且也只有这个2个目录。如果想要加入其他路径,则需要通过ldconfig命令配置相关文件。
一般ld-linux.so会按照以下顺序搜索共享库:
1、DT_RPATH或DT_RUNPATH段
2、环境变量LD_LIBRARY_PATH
3、/etc/ld.so.cache文件中的路径,但如果可执行程序在连接时候添加了-z nodeflib选项,则跳过。
4、默认路径/lib和/usr/lib,但如果添加了-z nodeflib,则跳过。


还有一些额外的环境变量可以参看man ld.so。


更为详细的内容:
1、man ldd(http://www.kernel.org/doc/man-pages/online/pages/man1/ldd.1.html)
2、man ldconfig(http://www.kernel.org/doc/man-pages/online/pages/man8/ldconfig.8.html)
3、man ld.so(http://www.kernel.org/doc/man-pages/online/pages/man8/ld.so.8.html)


可以参见的文章:
1、Linux 动态库剖析(http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/)
2、剖析共享程序库http://www.ibm.com/developerworks/cn/linux/l-shlibs.html)
3、ldd命令的原理与使用方法(http://hi.baidu.com/wstone_h/blog/item/af67700a80a01e1594ca6b29.html)

© 著作权归作者所有

共有 人打赏支持
lieefu
粉丝 87
博文 111
码字总数 23811
作品 3
济南
高级程序员
Linux命令-ldd

1.在制作自己的发行版时经常需要判断某条命令需要哪些共享库文件的支持,以确保指定的命令在独立的系统内可以可靠的运行; 在Linux环境下通过ldd命令即可实现,在终端下执行: ldd /bin/ls ...

稀饭桶子
2016/09/06
25
0
linux下疑难杂症问题需要使用的工具(strace用法与gdb用法与catchsegv)

今天服务器上跑的程序出现了异常。 kernel segfault at 0000000100000000 rip 0000000100000000 rsp 00007fff97d60fc8 error 14 kernel 报错,可以用dmesg命令查看 [root@MonitorANDBack ~]$......

caijyi1
06/26
0
0
Linux C 库的生成与使用

库文件的存在极大的提高了 C/C++ 程序的复用性,本文简单介绍如何生成、使用它们。 命名约定:我们一般对库文件约定以 开头,动态库文件一般以 (*nix)或 (Windows) 结尾,静态库文件一般...

傅易
2016/08/20
68
0
Linux 中如何快速查看 C 库函数的头文件、库文件

Linux 中如何快速查看 C 库函数的头文件以及相应的函数信息? 使用man帮助或grep 1)man命令 函数名,则能够打印该函数的所有说明,当然这个函数必须是Linux-C本身就有的函数。 2)grep "key...

byxdaz
05/20
0
0
关于linux下的共享库(动态库)和静态库

1.什么是库 在windows平台和linux平台下都大量存在着库。 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。 由于windows和linux的本质不同,因此二者库的二进制是不...

AlphaJay
2010/04/15
0
0
动态库和静态库的定义和区别

动态库与静态库定义与比较 我们在编写一个C语言程序的时候,经常会遇到好多重复或常用的部分,如果每次都重新编写固然是可以的,不过那样会大大降低工作效率,并且影响代码的可读性,更不利于...

huyawenz
2017/10/23
0
0
C/C++ Lib库文件nm调试之符号表

本文主要介绍了一下在Linux下开发c/c++时候,不可避免的会开发或者生成.o .a .so这种中间库状态的文件(可能是自己写了一个lib让别人调用,或者提供.c/.cpp文件嵌入别人的Makefile工程)。如何...

长平狐
2013/01/05
3.7K
0
关于Linux静态库和动态库的分析

1.什么是库 在windows平台和linux平台下都大量存在着库。 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。 由于windows和linux的本质不同,因此二者库的二进制是不...

YACHE
2011/07/04
0
0
unsupported hash type md5/sha1

错误形式: >>>inport hashlib ERROR:root:code for hash md5 was not found. … ValueError:unsupported hash type md5 … ERROR:root:code for hash sha1 was not found. … ValueError:u......

active_health
2016/06/02
133
0
OBJ文件格式分析工具: objdump, nm,ar

首先简要阐述关于gcc、glibc和 binutils模块之间的关系 一、关于gcc、glibc和binutils模块之间的关系 1、gcc(gnu collect compiler)是一组编译工具的总称。它主要完成的工作任务是“预处理...

AlphaJay
2010/09/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

数据库事务的四大特性以及事务的隔离级别

本篇讲述数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是...

Java大蜗牛
6分钟前
0
0
Spring Boot 整合 MyBatis/通用Mapper/PageHelper分页插件

整合MyBatis 整合通用Mapper 1. POM依赖配置 <properties><mapper.starter.version>2.0.3-beta1</mapper.starter.version></properties><!-- 通用Mapper --><dependency><groupId>t......

OSC_fly
14分钟前
0
0
CentOS7 双网卡绑定

环境 操作系统 CentOS7.5,禁用 NetworkManager 服务 网卡 eth0 网卡 eth1 绑定网卡 bond0 网卡 eth0 配置 修改 /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=EthernetBOOTPROTO=noneD......

Colben
16分钟前
0
0
zk实战--rpc框架集群化

在看此篇内容时需要浏览下面内容 netty实战--手写rpc框架 前文功能简介以及功能扩充 利用netty来实现一个点对点的rpc调用。客户端和服务端都是靠手写地址进行socket同学的,无法1对多,也无法...

xpbob
32分钟前
11
0
springboot 发送邮件

获取授权码 添加配置 # 账号和密码spring.mail.username=aaa@qq.comspring.mail.password=bbb# 服务器地址spring.mail.host=smtp.qq.comspring.mail.properties.mail.smtp.ssl.en...

阿豪boy
33分钟前
0
0
如何使用GNU Ring?

文章名:如何使用GNU Ring? 作者:冰焰火灵X 1079092922@qq.com 文章许可:CC BY-SA 4.0 ##1. 安装 下载GNU Ring 点击左边选择你的系统版本(这里以 GNU/Linux 为例,我使用的是Mint 18.3)...

ICE冰焰火灵X
35分钟前
4
0
深入理解springMVC

什么是spring MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而...

Java填坑之路
41分钟前
1
0
《射雕英雄传》书摘

1. 我虽是个飘泊江湖的贫家女子,可不是低三下四、不知自爱之人。你如真心爱我,须当敬我重我。我此生决无别念,就是钢刀架颈,也决意跟定了你。将来……将来如有洞房花烛之日,自然……自能...

k91191
52分钟前
1
0
解决:modal中datePicker 选中时,会触发modal的hidden.bs.modal事件

最近项目中发现了一个bug,具体表现为选中模态框上datepicker组件上的日期时,会触发模态框的关闭事件,导致数据编辑无法正常进行。网上搜索了下,解决方法如下: $('.datepicker').on('hid...

Funcy1122
55分钟前
0
0
Redis分布式锁的正确实现方式

前言 分布式锁一般有三种实现方式: 1.数据库乐观锁 2.基于Redis的分布式锁; 3.基于Zookeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。虽然网上已经有各种介绍Redis...

大海201506
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部