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

程序上经常有在这台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 myapplinux-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 shsudo 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 glibcabicheck/focal,focal 1.2-5ubuntu1 allbinary compatibility checking toolclisp/focal 1:2.49.20180218+really2.49.92-3build3 amd64GNU CLISP, a Common Lisp implementationfakeroot-ng/focal 0.18-4build2 amd64Gives a fake root environmentglibc-doc/focal-updates,focal-updates 2.31-0ubuntu9.12 allGNU C 库:文档glibc-doc-reference/focal,focal 2.30-1ubuntu1 allGNU C 库:文档glibc-source/focal-updates,focal-updates 2.31-0ubuntu9.12 allGNU 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.29U exp@GLIBC_2.29U log@GLIBC_2.29U log2@GLIBC_2.29U 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.hqwc.cn/news/282562.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java小案例-RocketMQ的11种消息类型,你知道几种?(请求应答消息)

前言 Rocket的请求应答消息是指在使用Rocket(这里可能是RocketMQ或者Rocket框架)进行通信时,客户端发送一个请求到服务端,然后服务端处理该请求并返回一个响应的过程中的数据交换。 在RocketMQ中: 请求应答消息通常…

用Kotlin抓取微博数据并进行热度预测

闲来无事,逛逛微博,看着每条热度很高的博文趣事,心想能否通过爬虫抓取微博热度并进行趋势分析,说干就干,这里需要注意的问题我会一一标注。 爬虫ip信息的设置是在爬虫程序中进行的。爬虫ip信息可以帮助爬虫程序在访问…

python排序算法 直接插入排序法和折半插入排序法

最近需要使用到一些排序算法,今天主要使针对直接插入排序和折半插入排序进行讲解。 首先是直接插入排序,其排序过程主要是,针对A[a1,a2,a3,a4,a5....an],从排序的序列头部起始位置开始,将其也就是a1视为只有一个元素的…

DC电源模块的设计与制造技术创新

BOSHIDA DC电源模块的设计与制造技术创新 DC电源模块的设计与制造技术创新主要涉及以下几个方面: 1. 高效率设计:传统的DC电源模块存在能量转换损耗较大的问题,技术创新可通过采用高效率的电路拓扑结构、使用高性能的功率开关器件和优化控制…

网络基础(十二):ACL与NAT

目录 一、ACL 1、ACL的概述 2、ACL的分类 3、ACL的应用 4、ACL的组成和基本原理 ​编辑 5、ACL的配置 5.1配置基本ACL 5.2配置高级ACL 二、NAT 1、NAT的概述 2、NAT的分类 3、NAT的工作原理 4、静态NAT的配置 5、动态NAT的配置 6、NAPT(端口映射&am…

机器学习 | 机器学习基础知识

一、机器学习是什么 计算机从数据中学习规律并改善自身进行预测的过程。 二、数据集 1、最常用的公开数据集 2、结构化数据与非结构化数据 三、任务地图 1、分类任务 Classification 已知样本特征判断样本类别二分类、多分类、多标签分类 二分类:垃圾邮件分类、图像…

NtripShare Mos监测平台边缘计算终端与自动优化平差算法

忙忙乎乎23年又要过去了,回头看今年做的事,只有两件事值得一提: 1、自动化监测边缘计算终端; 2、自动优化平差算法。 自动化监测边缘计算终端 终端采用全国产硬件方案终端支持全站仪供电控制终端支持远程控制终端支持数据缓存技…

神经网络可以计算任何函数的可视化证明

神经网络可以计算任何函数的可视化证明 对于神经网络,一个显著的事实就是它可以计算任何函数。 如下:不管该函数如何,总有神经网络能够对任何可能的输入x,输出值f(x) 即使函数有很多输入和输出&#xff0…

MPEG4Extractor

1、readMetaData 必须要找到 Moov box,找到 Mdat box或者 Moof box,并且创建了 ItemTable 大端 box 分为 box header 和 box content: box header由8个字节组成,前面四个字节表示这个box 的大小(包含这个头的8字节&a…

k8s - container

1、容器的生命周期: (1) 简介: Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样。 可以使用容器生命周期回调,在容器生命周期中的特定状态点触发事件。 ● 容器生命周期回调: 在容器的生…

NetSuite 智能商品推荐(Intelligent Recommendations)

本周在一个客户环境里,发现销售订单中有个Intelligent Recommendations的按钮。 本以为是客户新装的一个SuiteApp,仔细研究一下发现还不是。是个我们忽略的一个内建新功能。 Intelligent Recommendations,是2023.1版本推出的新功能。主要目的…

Unity Web 浏览器-3D WebView中有关于CanvasWebViewPrefab

一、CanvasWebViewPrefab默认设置 这个是在2_CanvasWebViewDemo示例场景文件中可以可以查看得到,可以看出CanvasWebViewPrefab的默认配置如下。 二、Web 浏览器网页和Unity内置UI的渲染顺序 1、如果你勾选了以下这个Native 2D Mode选项的话,那么Unit…