解决库依赖问题

starce 的另一个用处是解决和动态库相关的问题。当对一个可执行文件运行ldd时,它会告诉你程序使用的动态库和找到动态库的位置。但是如果你正在使用一个比较老 的glibc版本(2.2或更早),你可能会有一个有bug的ldd程序,它可能会报告在一个目录下发现一个动态库,但是真正运行程序时动态连接程序 (/lib/ld-linux.so.2)却可能到另外一个目录去找动态连接库。这通常因为/etc/ld.so.conf和 /etc/ld.so.cache文件不一致,或者/etc/ld.so.cache被破坏。在glibc 2.3.2版本上这个错误不会出现,可能ld-linux的这个bug已经被解决了。

尽管这样,ldd并不能把所有程序依赖的动态库列出 来,系统调用dlopen可以在需要的时候自动调入需要的动态库,而这些库可能不会被ldd列出来。作为glibc的一部分的NSS(Name Server Switch)库就是一个典型的例子,NSS的一个作用就是告诉应用程序到哪里去寻找系统帐号数据库。应用程序不会直接连接到NSS库,glibc则会通 过dlopen自动调入NSS库。如果这样的库偶然丢失,你不会被告知存在库依赖问题,但这样的程序就无法通过用户名解析得到用户ID了。让我们看一个例子:
whoami程序会给出你自己的用户名,这个程序在一些需要知道运行程序的真正用户的脚本程序里面非常有用,whoami的一个示例 输出如下:

  1. # whoami
    root

假设因为某种原因在升 级glibc的过程中负责用户名和用户ID转换的库NSS丢失,我们可以通过把nss库改名来模拟这个环境:

  1. # mv /lib/libnss_files.so.2 /lib/libnss_files.so.2.backup
    # whoami
    whoami: cannot find username for UID 0

这里你可以看到,运行whoami时出现了错误,ldd程序的输出不会提供有用的帮助:

  1. # ldd /usr/bin/whoami
    libc.so.6 => /lib/libc.so.6 (0x4001f000)
    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

你只会看到whoami依赖Libc.so.6和ld-linux.so.2,它没有给出运行whoami所必须的其他库。这里时用strace跟踪 whoami时的输出:

  1. strace -o whoami-strace.txt whoami
  2.  
  3. open("/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i686/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    stat64("/lib/i686/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)
    open("/lib/i686/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    stat64("/lib/i686", 0xbffff190) = -1 ENOENT (No such file or directory)
    open("/lib/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    stat64("/lib/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)
    open("/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    stat64("/lib", {st_mode=S_IFDIR|0755, st_size=2352, ...}) = 0
    open("/usr/lib/i686/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
    stat64("/usr/lib/i686/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i686/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

你可以发现在不同目录下面查找libnss.so.2的尝试,但是都失败了。如果没有strace这样的工具,很难发现这个错误是由于缺少动态库造成的。现 在只需要找到libnss.so.2并把它放回到正确的位置就可以了。 

正常的输出情况:

execve("/usr/bin/whoami",["/usr/bin/whoami"],[/* 24 vars */]) = 0  //execve为strace输出系统调用中的第一个,调用execve加载需要执行的程序

brk(0)                                                 =0x229a000     //调用brk,参数为零,返回内存管理的其实地址(如果子进程中调用malloc,从0x9ac4000地址开始分配空间)

mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f909809c000 //使用mmap函数进行匿名内存映射,长度为4096bytes内存空间,起始地址0x7f909809c000,主要起到申请内存的作用

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)  //调用access函数判断当前用户对/etc/ld.so.preload 是否可读[R_OK,W_OK,X_OK,F_OK,读取,写入,执行,是否存在],check real user's permissions for a file

open("/lib64/libc.so.6", O_RDONLY) = 3  //打开文件,只读模式[O_RDONLY,O_WRONLY,O_RDWR,只读,只写,读写]

fstat(3,{st_mode=S_IFREG|0644,st_size=36400, ...}) = 0 //根据文件描述符 3,获取文件信息;S_IFREG 文件是一个普通文件

mmap(NULL,36400,PROT_READ,MAP_PRIVATE,3,0) = 0x7f9098090000 //把文件描述符3映射到内存,私有模式

close(3) = 0 //关闭文件描述符3

open("/lib64/libc.so.6", O_RDONLY) = 3

read(3,"/177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\355\1\0\0\0\0\0"...,832) = 832 //读取文件描述符3中832bytes的内容,

fstat(3,{st_mode=S_IFREG|0755,st_size=1916568,...}) = 0

mmap(NULL,3745960,PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_DENYWRITE,3,0) = 0x7f9097ae7000

mprotect(0x7f9097c71000,2093056,PROT_NONE) = 0

...

arch_prctl(ARCH_SET_FS, 0x7f909808f700) = 0  // set architecture-specific thread state,set the 64-bit base for the FS register to addr

....(未完)

转载自:http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316692.html

strace 解决库依赖问题的更多相关文章

  1. OpenWRT开发之——对C++的支持(解决库依赖问题)【转】

    转自:https://my.oschina.net/hevakelcj/blog/411944 摘要: 本文尝试用C++来开发一个cpp-demo包 遇到打包库依赖的问题,分析打包过程并解决了这个问题 ...

  2. Android Studio 解决 Gradle 依赖冲突的问题

    Android Studio 解决 Gradle 依赖冲突的问题 参考链接: Android Studio(Gradle)解决库依赖冲突问题:http://www.mobibrw.com/2016/3 ...

  3. Android下查看共享库依赖项

    Android下查看共享库依赖项 [时间:2017-02] [状态:Open] [关键词:android,共享库依赖项,so,ndk,objdump,readelf] 起因 近期在处理Android下 ...

  4. linux 下 奇怪的 动态库 依赖问题

    转:http://fanwei51880.blog.163.com/blog/static/3240674020111145285375/ 总结如下:1)当你在编译生成静态库的时候, 只需要相应的依赖 ...

  5. Android Studio库依赖问题

    Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'. > com.android. ...

  6. Linux 桌面玩家指南:17. 在 Ubuntu 中使用 deepin-wine,解决一些依赖 Windows 的痛点问题

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  7. Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题)

    Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) rpm安装gcc时碰到的有关问题解决(解决gcc依赖有关问题) 提示:error: Failed dependencies: clo ...

  8. Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明

    本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法: 1.添加动态库(直接添加动态库文件.dll,非子项目) 通过qtcreator创建动态库的方法就不在此 ...

  9. Java-idea-常用技巧-转maven,解决包依赖冲突

    1.Intellij IDEA如何将普通工程转换成maven工程 项目上右键 Add Framework Support,选择maven 2.Intellij IDEA 自动生成 serialVers ...

随机推荐

  1. TYVJ 4354 多重背包二进制优化

    直接放代码了 #include <cstdio> #include <cstring> #include <algorithm> using namespace s ...

  2. PHP mysql_fetch_array() 函数

    PHP mysql_fetch_array() 函数 从结果集中取得一行作为关联数组,或数字数组,或二者兼有.返回根据结果集取得的行生成的数组,如果没有更多行则返回false. 提示:有很重要的一点必 ...

  3. Django后台post请求中的csrf token

    使用Requests库操作自己的Django站点,post登陆admin页面返回403,serverlog显示csrf token not set. csrf token是get登陆页面时服务器放在c ...

  4. maven加载jar包配置

    maven build时报程序包不存在和找不到符号的错误,但是代码中不报错,如下: [ERROR] Failed to execute goal org.apache.maven.plugins:ma ...

  5. 浅谈VB.Net 程序的编译和动态编译

    ---恢复内容开始--- 一般,我们都是通过Visual Studio(下面简称vs)来编写和编译vb.net应用程序的,但是,不少的人并不知道vs是通过何种方式编译程序的.今天,我们就来探讨一下编译 ...

  6. BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2375  Solved: 1005[Submit][Sta ...

  7. 博客开篇:随笔《从windows到linux的转变》。

    在QQ群里讨论到了WINDOWS和LINUX.MAC,用手机码了如下回复,索性转过来当做博客的开篇.:) unix 和linux 在外很火的主要原因是开源,国外崇尚自由的精神是从出生就在细胞里的,而w ...

  8. Java ResourceBundle类的使用

    1.使用ResourceBundle读取配置文件 #数据库配置信息: DRIVER=com.mysql.jdbc.Driver URL=jdbc:mysql://localhost:3306/dmo ...

  9. Xcode 各个版本下载地址

    从Xcode8开始不支持uiautomation了,需要下载老版本的xcode Xcode 的各种版本的下载地址  https://developer.apple.com/download/more/

  10. Mybatis Generator自动生成的mapper只有insert方法

    – Mybatis Generator 生成的mapper只有insert方法 – 首先检查generatorConfig.xml中table项中的属性 enableSelectByPrimaryKe ...