• 【workaround】可执行文件(编译时)glibc版本小于运行环境(运行时)glibc版本


    Q1. /lib64/libm.so.6: version `GLIBC_2.29’ not found

    Q1. 网上下载了一个软件压缩包,解压后只有可执行文件。运行可执行文件时报错如下。

    ...: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ...)
    
    • 1

    A1. 通过ldd --versionstrings /lib64/libm.so.6 |grep ^GLIBC_等命令,确认机器上没有2.29版本。因此下载安装新版本。

    wget -c https://ftp.gnu.org/gnu/glibc/glibc-2.29.tar.gz
    tar -zxvf glibc-2.29.tar.gz
    cd glibc-2.29
    mkdir build
    cd build
    sudo ../configure --prefix=/new/path/glibc
        #该步骤可能出现missing or too old错误,详见Q1b;
    sudo make
    sudo make install
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    参考
    https://stackoverflow.com/questions/74740941/how-can-i-resolve-this-issue-libm-so-6-version-glibc-2-29-not-found-c-c

    Q1b. *** These critical programs are missing or too old: make

    Q1b. 执行上述A1中的configure时,可能出现以下错误。

    *** These critical programs are missing or too old: make
    *** Check the INSTALL file for required versions.
    
    • 1
    • 2

    该错误的出现可能是make版本过老,或configure文件关于make版本正则不匹配造成的。
    前者需要安装符合版本要求的make。后者需要修改configure文件中make版本正则匹配规则。

    #yum group install "Development Tools"
     
    #yum install centos-release-scl
    #yum install -y devtoolset-7
    #scl enable devtoolset-7 bash
    
    • 1
    • 2
    • 3
    • 4
    • 5

    参考
    https://stackoverflow.com/questions/69485181/how-to-install-g-on-conda-under-linux
    https://superuser.com/questions/1640048/how-to-properly-upgrade-gcc-on-centos-7

    Q2. Segmentation fault (core dumped)

    安装完新版本的GLIBC后,本来打算将路径导入LD_LIBRARY_PATH,然后执行命令,但出现新的报错。

    export LD_LIBRARY_PATH=/new/path/glibc/2.29 && ./your_app
    Segmentation fault (core dumped)
    
    • 1
    • 2

    综合网上查阅资料,应该是编译时的glibc库和运行时的glibc库版本不一致造成的。由于没有源码,无法重新编译,只能在运行时想办法,目前有两种方案可以解决该问题。
    参考
    https://unix.stackexchange.com/questions/272606/locally-installing-glibc-2-23-causes-all-programs-to-segfault
    https://stackoverflow.com/questions/847179/multiple-glibc-libraries-on-a-single-host
    https://stackoverflow.com/questions/19709932/segfault-from-ld-linux-in-my-build-of-glibc

    A2-方案1:ld-linux-x86-64.so.2方法

    # 方案1. 匹配版本
    /new/path/glibc/2.29/lib/ld-linux-x86-64.so.2 --library-path . ./your_app
    
    • 1
    • 2

    方案1无需修改可执行文件,结合脚本封装快速方便。缺点是一旦可执行文件中嵌套了其它可执行文件,该方法就无能无力了。

    A2-方案2:patchelf方法

    # 安装
    #git clone https://github.com/NixOS/patchelf.git
    git clone https://gitee.com/rysben/patchelf.git
    cd patchelf
    ./bootstrap.sh
    ./configure
      # *** A compiler with support for C++17 language features is required.
      # 总出这种报错很烦,笔者后面直接开了台云机器安装patchelf,然后将可执行文件上传、修改、然后传回。各位老铁也可以安装C++试试看。
    make
    make check
    sudo make install
    
    # 修改
    /patchelf --set-interpreter /new/path/glibc/2.29/lib/ld-linux-x86-64.so.2 --set-rpath /new/path/glibc/2.29/lib/  your_app1
    /patchelf --set-interpreter /new/path/glibc/2.29/lib/ld-linux-x86-64.so.2 --set-rpath /new/path/glibc/2.29/lib/  your_app2
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方案2使用patchelf可以修改相关ELF/可执行文件中的动态加载器和运行时搜索路径。

    参考
    https://github.com/NixOS/patchelf

  • 相关阅读:
    【Linux】gdb工具使用
    Python实现print输出至日志文件
    mac. homebrew bundle dump 失败 status 128
    【05】Spring源码-手写篇-手写Bean配置
    boot引导升级,成功引导运行loader
    Linux权限
    Helm3模板-其他注意事项
    React - 01
    如何为 Python 应用选择最好的 Docker 镜像?
    SQL的delete和drop
  • 原文地址:https://blog.csdn.net/sinat_39288981/article/details/133856393