version `GLIBC_2.29‘ not found 的原因和怎么解决问题

news2024/10/5 23:28:59

程序上经常有在这台Linux上编译,然后放到另一个Linux上运行的情况。

如果Linux版本差别不大或都是ubuntu或centos系列还好。

如果不是一个系列很容易出现GLIBC 找不到的情况。

尤其是ubuntu上编译,然后放到centos系列。因为centos为了追求所谓的稳定,基本用的都是N年前的东西,生怕用新的东西把它给搞的不安全了。

ImportError: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by /home/ma-user/_openjar.so)

问题的本质

这个问题的本质就是,编译所用的GLIBC的版本高,但是运行的机子上的GLIBC版本低,没有所用的GLIBC_2.29的相关函数接口。

所以应该怎么办呢? 通过ldd可以看到程序所依赖的.so库

/tmp> ldd myapp
        linux-vdso.so.1 =>  (0x00007fff7a1ff000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1f8a765000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1f8a4e3000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1f8a2cc000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1f89f45000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1f8aaa9000)
/tmp>

可以看到有libstdc++, libm, libgcc, and libc

其中libstdc++是gcc的c++ 动态库。

libc.so 和libm.so 都是GLIBC的一部分。

通过objdump可以看到 我们的程序myapp所调用的一些接口函数的版本号。

/tmp> objdump -T myapp | grep GLIBC_
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 ungetc
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   __ctype_toupper_loc
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 fputc
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
…
/tmp>

第一点是把c++库给静态链接了。

-static-libstdc++ 选项可以让g++静态链接c++库,就是 libstdc++

g++ -static-libstdc++ 

第二点是 C库静态链接,但这一条可能存在问题

-static 选项会把所有的库静态链接,但是这个可能存在问题,比如不兼容。

还有一个问题是License的问题,有些GPL的代码如果静态链接了,你的程序是不是也要GPL。

虽然GLIBC对静态链接是有豁免license的。但是其他代码可说不准。

虽然License有时候也不是问题。

g++ -static

解决办法

一、最根本的办法

搞一个跟目标机一样的系统,进行编译。 

如果目标机不确定,你又希望最好的兼容性,就尽量用低版本的系统进行编译。比如有人用ubuntu-16.04进行编译,编译出来的在ubuntu20.04上肯定是能用的。

现在docker技术已经非常发达了,都不需要装虚拟机。

直接在docker 镜像中进行编译就可以了。

比如:kroggen/ubuntu-16.04-gcc 这个镜像。

升级gcc

但是这个时候又会有另外一个问题。 就是旧版本系统上的编译器有点旧。

比如centos 7.7上的默认编译是gcc -v4.8.2,太老掉牙了。

现在谁不是c++14  c++17特性用的飞起。 

随便一个都要gcc v9.3甚至更高。

当然自己编译一个高版本的gcc是可以的。但centos上有epel已经提供了可以yum的高版本gcc,直接进行yum就可以了。

# install gcc 9 on centos 7
# https://gist.github.com/superzscy/ea619f881c92b8cdae8faaf782d0f031
yum install -y centos-release-scl
yum install -y devtoolset-9
scl enable devtoolset-9 bash

ubuntu上也有提供一些低版本系统上用的gcc 9

#!/usr/bin/env sh

sudo apt-get update -y && \
sudo apt-get upgrade -y && \
sudo apt-get dist-upgrade -y && \
sudo apt-get install build-essential software-properties-common -y && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update -y && \
sudo apt-get install gcc-9 g++-9 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9 && \
sudo update-alternatives --config gcc

# select gcc-9

常见的系统所用的glibc的版本.

Distributionglibc version
Debian 72.13
Debian 82.19
Debian 92.24
CentOS 62.12
CentOS 72.17
Ubuntu 14.042.19
Ubuntu 16.042.23
Ubuntu 18.042.27

Ubuntu 20.04                                                        2.31

查看系统的glibc的版本可以用以下命令:

ubuntu 上 apt search glibc

apt search glibc


abicheck/focal,focal 1.2-5ubuntu1 all
  binary compatibility checking tool

clisp/focal 1:2.49.20180218+really2.49.92-3build3 amd64
  GNU CLISP, a Common Lisp implementation

fakeroot-ng/focal 0.18-4build2 amd64
  Gives a fake root environment

glibc-doc/focal-updates,focal-updates 2.31-0ubuntu9.12 all
  GNU C 库:文档

glibc-doc-reference/focal,focal 2.30-1ubuntu1 all
  GNU C 库:文档

glibc-source/focal-updates,focal-updates 2.31-0ubuntu9.12 all
  GNU C 库:源代码

 欧拉系统:

yum info glibc-devel

[root@host-13 ~]# yum info glibc-devel
Last metadata expiration check: 2:18:51 ago on Fri 15 Dec 2023 08:56:55 AM CST.
Installed Packages
Name         : glibc-devel
Version      : 2.28
Release      : 49.oe1
Architecture : aarch64
Size         : 9.4 M
Source       : glibc-2.28-49.oe1.src.rpm
Repository   : @System
From repo    : anaconda
Summary      : The devel for glibc
URL          : http://www.gnu.org/software/glibc/
License      : LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL
Description  : The glibc-devel package contains the object files necessary for developing
             : programs which use the standard C libraries. Besides, it contains the
             : headers. Thus, it is necessory to install glibc-devel if you ned develop programs.

二、patchelf 直接干

用patchelf把版本的信息删掉,自动链接系统上的相关函数。

patchelf位于:

GitHub - NixOS/patchelf: A small utility to modify the dynamic linker and RPATH of ELF executables

用法如下: 

$ nm --dynamic --undefined-only --with-symbol-versions MyLib.so \
  | grep GLIBC | sed -e 's#.\+@##' | sort --unique
GLIBC_2.17
GLIBC_2.29
$ nm --dynamic --undefined-only --with-symbol-versions MyLib.so | grep GLIBC_2.29
                 U exp@GLIBC_2.29
                 U log@GLIBC_2.29
                 U log2@GLIBC_2.29
                 U pow@GLIBC_2.29
$ patchelf --clear-symbol-version exp   \
           --clear-symbol-version log   \
           --clear-symbol-version log2  \
           --clear-symbol-version pow   MyLib.so

但这种太猛了,不一定起作用。

三、指定glibc的版本

还有一个办法,就是gcc提供了一种指定库函数版本号的方法。

__asm__(".symver SYM,SYM@GLIBC_VERSION");

详情参见这个项目:

GitHub - wheybags/glibc_version_header: Build portable Linux binaries without using an ancient distroBuild portable Linux binaries without using an ancient distro - GitHub - wheybags/glibc_version_header: Build portable Linux binaries without using an ancient distroicon-default.png?t=N7T8https://github.com/wheybags/glibc_version_header

这个项目有点老了,有些函数不一定行,但是思路是没有问题的。

参考:

linux - How can I link to a specific glibc version? - Stack Overflow

Florian Weimer - Re: how to compile a lower gcc/glibc version compatible binary?

 https://insanecoding.blogspot.com/2012/07/creating-portable-linux-binaries.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1314503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机组成原理-选择语句和循环语句的汇编表示

文章目录 选择语句jmpjxx示例:选择语句的机器级表示扩展:cmp指令的底层原理 循环语句使用条件转移指令实现循环用loop指令实现循环 选择语句 不一定知道指令的位置,所以jmp直接跳转到指令的位置很难办 jmp 标号相当于位置,名字…

生产派工自动化:MES系统的关键作用

随着制造业的数字化转型和智能化发展,生产派工自动化成为了提高生产效率、降低成本,并实现优质产品生产的关键要素之一。制造执行系统(MES)在派工自动化中发挥着重要作用,通过实时数据采集和智能调度,优化生…

Ubuntu虚拟机怎么设置静态IP

1 首先先ifconfig看一下使用的是哪个网络接口: 2 编辑 sudo vi /etc/netplan/00-installer-config.yamlnetwork:ethernets:ens33: # 根据您的网络接口进行修改,有的是eth0,有的是ens33,具体看第一步显示的是哪个网络接口addres…

【答案】2023年国赛信息安全管理与评估第三阶段夺旗挑战CTF(网络安全渗透)

【答案】2023年国赛信息安全管理与评估第三阶段夺旗挑战CTF(网络安全渗透) 全国职业院校技能大赛高职组信息安全管理与评估 (赛项) 评分标准 第三阶段 夺旗挑战CTF(网络安全渗透) *竞赛项目赛题* 本文…

【算法与数据结构】53、LeetCode最大子数组和

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:程序一共两个变量,一个result一个count。result用来记录最终的结果,count记录当…

针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法

针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法 文章目录 针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法Abstractscreen和tmux介绍tmux常用命令以及快捷键Byobu简单操作步骤集锦参考文献 Abstract PyTorch多卡并行运行程序is one of the mos…

Leetcode sql50基础题最后的4题啦

算是结束了这个阶段了,之后的怎么学习mysql的方向还没确定,但是不能断掉,而且路是边走边想出来的。我无语了写完了我点进去看详情都不让,还得重新开启计划,那我之前的题解不都没有了!! 1.第二高…

Winform高效获取控件(Control)方法 + 源码分析

背景:风好大,睡觉有点怕,起床敲代码了 之前学的都是都是通过遍历控件(Controls),判断控件名是否相等来获取Control 其实直接通过:Controls["控件名"],就可以获得需要的控件 为什么呢…

【Java JVM】运行时数据区

JVM 在执行 Java 程序的过程中会把它管理的内存分为若干个不同的数据区域, 这些区域有着各自的用途。 根据《Java虚拟机规范》中规定, JVM 所管理的内存大致包括以下几个运行时数据区域, 如图所示: 这个运行时数据区被分为了 5 大块 方法区 (Method Area)堆 (Heap)虚拟机栈 (V…

npm ,yarn 更换使用国内镜像源,阿里源,清华大学源

在平时开发当中,我们经常会使用 Npm,yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的,如果没有梯子的话。会感觉特别特别慢,所以,使用国内的源是非常有必要的。 在这里插入图片描述 Nnpm, yarn …

我的NPI项目之Android 安全系列 -- 先认识一下ST33Jxxx

目前接触过的高通平台都没有集成单独的SE,安全运行环境都是高通自家的TEE,又言Trustzone。高通Keystore功能也是依赖TEE来实现的。那么,如果另外集成SE,那么高通的Keystore如何集成?TEE部分要如何配置? 最近…

软件设计规约和评审

软件设计规约 概要设计规约:这是面向软件开发者的文档,主要作为软件项目管理人员、系统分析人员与设计人员之间交流的媒介。它指明了软件的组织结构,主要内容包括: 系统环境:硬件、软件接口与人机界面;外部…

大模型下开源文档解析工具总结及技术思考

1 基于文档解析工具的方法 pdf解析工具 导图一览: PyPDF2提取txt: import PyPDF2 def extract_text_from_pdf(pdf_path):with open(pdf_path, rb) as file:pdf_reader PyPDF2.PdfFileReader(file)num_pages pdf_reader.numPagestext ""f…

WX小程序案例(一):弹幕列表

WXML内容 <!--pages/formCase/formCase.wxml--> <!-- <text>pages/formCase/formCase.wxml</text> --> <view class"bk bkimg"><!-- <image src"/static/imgs/ceeb653ely1g9na2k0k6ug206o06oaa8.gif" mode"scal…

【专题】树和二叉树的转换

目录 一、树转换成二叉树步骤一&#xff1a;加线——在兄弟之间加连线步骤二&#xff1a;抹线——除结点的左孩子外&#xff0c;去除其与其余孩子之间的关系步骤三&#xff1a;旋转——以树的根结点为轴心&#xff0c;将整树顺时针转45 二、二叉树转换成树步骤1&#xff1a;加线…

MQ入门—centos 7安装RabbitMQ 安装

三&#xff1a;RabbitMQ 安装 1.环境准备 Linux 的 CentOS 7.x 版本。Xftp 传输安装包到 Linux。Xshell 连接 Linux&#xff0c;进行解压安装。 RabbitMQ安装包 链接&#xff1a;https://pan.baidu.com/s/1ZYVI4YZlvMrj458jakla9A 提取码&#xff1a;dyto xshell安装包 链接&…

053:vue工具--- 英文字母大小写在线转换

第047个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

拼多多买家页面批量导出订单excel

拼多多买家页面批量导出订单excel 由于拼多多不支持订单导出excel清算起来很麻烦&#xff0c;就自己写了一个页面批量导出脚本代码。 首先打开拼多多手机端网站&#xff1a;https://mobile.pinduoduo.com/ 登录后点击我的订单打开f12审查元素 在控制台引入jquery&#xff0c;引…

四十二、Redis

目录 一、简介 二、Redis基础 三、Redis的持久化 四、Redis主从、哨兵、分片集群安装 五、Redis主从 六、Redis哨兵 七、Redis分片集群 一、简介 Redis是一个内存中的数据结构存储系统&#xff0c;可以用作数据库、缓存和消息中间件。它的数据结构包括字符串、列表、集合…

BearPi Std 板从入门到放弃 - 先天神魂篇(7)(RT-Thread 定时器-硬件定时器)

简介 BearPi IOT开发板 硬件定时器使用步骤 创建项目 参考 BearPi RT-Thread项目创建 RT-Thread TIM2 设备注册 宏定义添加 rtconfig.h 中添加 #define RT_USING_HWTIMER #define BSP_USING_TIM #define BSP_USING_TIM2生成支持TIM2的mdk5项目工程 env 指令 scons --t…