linux ldd命令学习

ldd命令用来显示可执行程序的dependency,
sh-# ldd ./test_main
        libc.so.6 => /lib/libc.so.6 (0x40113000)
        /lib/ld-linux.so.3 (0x40022000)
sh-#

sh-# ldd -d ./test_main
        libc.so.6 => /lib/libc.so.6 (0x4011a000)
        /lib/ld-linux.so.3 (0x400f4000)
sh-#

sh-# ldd -r ./test_main
        libc.so.6 => /lib/libc.so.6 (0x401d4000)
        /lib/ld-linux.so.3 (0x400fb000)
sh-#

sh-# ldd -v ./test_main
        libc.so.6 => /lib/libc.so.6 (0x4009d000)
        /lib/ld-linux.so.3 (0x40077000)

        Version information:
        ./test_main:
                libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
        /lib/libc.so.6:
                ld-linux.so.3 (GLIBC_2.4) => /lib/ld-linux.so.3
                ld-linux.so.3 (GLIBC_PRIVATE) => /lib/ld-linux.so.3
sh-#

ldd命令本身不是一个可执行程序,它只是一个shell脚本,
sh-# which ldd
/usr/bin/ldd
sh-#
sh-# ldd /usr/bin/ldd
        not a dynamic executable
sh-#
sh-# ldd /bin/ln
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40061000)
        libc.so.6 => /lib/libc.so.6 (0x400cd000)
        /lib/ld-linux.so.3 (0x4003b000)
sh-#
sh-# ldd /bin/top
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x401b6000)
        libc.so.6 => /lib/libc.so.6 (0x401c9000)
        /lib/ld-linux.so.3 (0x40013000)
sh-#

sh-# ls -lh /lib/libc.so.6
lrwxrwxrwx 1 root root 14 Nov  6 08:28 /lib/libc.so.6 -> libc-2.12.2.so
sh-# ls -lh /lib/libc-2.12.2.so
-rwxr-xr-x 1 root root 1.2M Nov  6 08:28 /lib/libc-2.12.2.so
sh-#

sh-# ls -lh /lib/ld-linux.so.3
lrwxrwxrwx 1 root root 12 Nov  6 08:28 /lib/ld-linux.so.3 -> ld-2.12.2.so
sh-# ls -lh /lib/ld-2.12.2.so
-rwxr-xr-x 1 root root 120K Nov  6 08:28 /lib/ld-2.12.2.so
sh-#

sh-# ./test_main &
31631
sh-#
<xulin>test_main

sh-#
sh-# ps aux | grep test_main
root      1304  0.0  0.1   1728   544 ?        S+   12:13   0:00 grep test_main
root      2324  0.0  0.1   1460   324 ?        S+   11:22   0:00 ./test_main
root     31631  0.0  0.1   1460   324 ?        S+   12:10   0:00 ./test_main
sh-#

ldd命令的工作原理是通过设置一些环境变量来实现的,这些环境变量包括:
LD_TRACE_LOADED_ONJECTS、LD_WARN、LD_DEBUG、LD_VERBOSE、...
比如默认情况下执行ldd命令就会设置LD_TRACE_LOADED_ONJECTS,所以就能查看各个可执行程序的dependency。
sh-# ldd ./test_main
        libc.so.6 => /lib/libc.so.6 (0x400e7000)
        /lib/ld-linux.so.3 (0x40068000)
sh-#

可以手动设置这个环境变量,然后在执行test_main程序,
sh-# export LD_TRACE_LOADED_OBJECTS=1
sh-# ./test_main
        libc.so.6 => /lib/libc.so.6 (0x400ca000)
        /lib/ld-linux.so.3 (0x400a4000)
sh-#

使用unset命令将这个环境变量删除,即可恢复原状了,
sh-# unset  LD_TRACE_LOADED_OBJECTS
sh-# ./test_main &
26003
sh-#
<xulin>test_main

sh-#

ldd命令工作原理其实质上是通过ld-linux.so来实现的,
ld-linux.so会先于可执行程序工作并获得控制权。
实际上可以直接使用ld-linux.so来查看可执行程序的共享库依赖关系。
sh-# /lib/ld-linux.so.3 --list ./test_main
        libc.so.6 => /lib/libc.so.6 (0x40204000)
        /lib/ld-linux.so.3 (0x4005a000)
sh-#
sh-# ldd ./test_main
        libc.so.6 => /lib/libc.so.6 (0x40180000)
        /lib/ld-linux.so.3 (0x40077000)
sh-#

可以试验将libc.so.6删除掉,再来看是否可以执行test_main这个程序。
通过确认发现,/lib/所在的文件系统为只读文件系统,所以无法进行删除操作。
sh-# rm /lib/libc.so.6
rm: cannot remove `/lib/libc.so.6': Read-only file system
sh-#
sh-# mountpoint /lib/
/lib/ is not a mountpoint
sh-#
sh-# stat -f /lib/
  File: "/lib/"
    ID: fe0000000000 Namelen: 256     Type: ooxx
Block size: 131072
Blocks: Total: 59         Free: 0          Available: 0
Inodes: Total: 1028       Free: 0
sh-#

但是基于试验的目的,可以通过设置环境变量LD_LIBRARY_PATH来达到目的,
即将/lib/从LD_LIBRARY_PATH中删除掉,这样在运行test_main程序时就会无法
找到动态链接库,从而造成程序执行错误。
但是实际情况是:
1. sh-# echo $LD_LIBRARY_PATH中并没有/lib目录;
2. test_main测试程序仍然可以正确运行。
sh-# echo $LD_LIBRARY_PATH

sh-#
sh-# ./test_main &
6663

<xulin>test_main
sh-#

可以参考下面这篇了解LD_LIBRARY_PATH与动态链接库的基本知识,
http://blog.csdn.net/boyxulin1986/article/details/11071671

关于ldd工作原理,本文先不做详细的学习;
不过后面有机会的话,可能会进行ldd第二篇学习,届时再对这一块做更深入的学习。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值