ldd命令排查文件crash的问题

作者: My熊猫眼 | 来源:发表于2020-02-22 10:11 被阅读0次

    在讲解case之前,需要首先讲解ldd命令:

    ldd到底是做什么的?

    ldd用来输出二进制可执行文件或者库文件的依赖;它本是一个script, 并不是binary 文件,其本质上只是设置了环境变量: D_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE(请参考ldd脚本文件的内容查看具体设置的环境变量)等。当通过export LD_TRACE_LOADED_OBJECTS=VALUE设置变量(该变量的值无所谓)后,那么无论执行任何的二进制可执行文件:都会显示该二进制文件对应的依赖;其效果和ldd 命令一样;

    那么为什么设置了上述变量之后,可执行的二进制文件就变成显示 对应的依赖呢?

    因为二进制文件被调用之前,优先调用了系统的/lib/ld-linux.so.2,这个动态库是一个可执行文件;该动态库运行的时候根据设置的环境变量,选择 显示的属性:可执行文件对应的依赖;所以其实是ld-linux.so.2这个模块把可执行二进制文件或者库文件的依赖显示出来了;

    1. 如果我们运行ld-linux.so.2这个模块,发现有一个--list参数,对于模块文件,我们除了用 ldd命令,也可以用ld-linux.so.2 --list MODILE_FILE_PATH 来显示依赖;
    2. 对于二进制可执行文件,也有两种方式来显示依赖: ldd命令,以及 用export LD_TRACE_LOADED_OBJECTS 设置变量后,直接执行二进制文件;

    用ldd命令可以成功列出文件的依赖,那么就有办法来排除文件crash导致的问题,下面用一个case来介绍大致的处理过程:

    文件crash通常会出现的现象有: core dump 提示, segment fatal 错误提示等;对于这些错误,很多情况下是文件的crash导致的;这时候要找出发生了错误的文件,然后进行修复:
    问题出现:

    [root@www ~]# rpcbind 
    Segmentation fault (core dumped)
    [root@www ~]#
    

    调用ldd命令来显示依赖:

    [root@www ~]# ldd `which rpcbind`
        linux-vdso.so.1 =>  (0x00007ffe87db4000)
        libtirpc.so.1 => /lib64/libtirpc.so.1 (0x00007f90e624f000)
        libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f90e601e000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f90e5e02000)
        libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f90e5bf7000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f90e582a000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007f90e5625000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f90e5323000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f90e511b000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f90e4ef4000)
        liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f90e4cce000)
        liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f90e4ab9000)
        libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f90e4838000)
        libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f90e4633000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f90e441a000)
        libdw.so.1 => /lib64/libdw.so.1 (0x00007f90e41cb000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f90e3fc7000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f90e3db1000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f90e6689000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f90e3b97000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007f90e3992000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f90e3730000)
        libelf.so.1 => /lib64/libelf.so.1 (0x00007f90e3518000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f90e3302000)
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f90e30f2000)
    [root@www ~]# 
    

    对上述的文件,验证其完整性,怎么做呢?
    如果这个文件是rpm包提供的,那么可以通过rpm -V PACKAGE 来验证文件的完整性;
    这里省略验证的命令(用组合命令一条就可以实现,自己试下吧!),结果如下:


    image.png

    在上面的结果中,可以发现 /lib64/libtirpc.so.1.0.10 这个文件的大小(S)以及修改时间(M)发生了变化,而这个文件是一个库文件,所以大小发生变化很值得怀疑;
    重新安装这个文件所在的包,然后解决问题.

    思考:

    这个case是可以reproduce的,那么你怎么来手动破坏一个命令/服务,然后用上述的思路来解决呢?

    提示: 用lsof 的结果来统计库文件都被哪些进程在使用,比如上面的/lib64/libtirpc.so.1.0.10, 统计之后就发现:只有rpcbind使用这个库文件,所以破坏这个库文件,那么有且只有rpcbind命令不能正常工作;剩下的就是按照上面的思路进行fix了哦!之所以要统计lsof的结果,以防止破坏了系统中影响面很大的库文件,毕竟只是为了学习嘛,达到目的即可.

    相关文章

      网友评论

        本文标题:ldd命令排查文件crash的问题

        本文链接:https://www.haomeiwen.com/subject/junhqhtx.html