【Linux】GLIBCXX 错误的深度理解

2025-04-13T14:17:06+08:00 | 5分钟阅读 | 更新于 2025-04-13T14:17:06+08:00

Macro Zhao

【Linux】GLIBCXX 错误的深度理解

推荐超级课程:

@TOC

如果您使用企业级或稳定的 Linux 发行版,迟早您会看到如下错误:

app: /lib64/libc.so.6: version `GLIBC_3.1.45' not found (required by ./app)

或者像这样:

app: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./app)

应用程序(或库)本身会有所不同。libclibstdc++ 的路径也可能不同。但错误总是会提到未找到 GLIBCXXGLIBC 版本。 您可以做些什么来修复它呢?

什么是 glibclibstdc++

一些背景知识将帮助您更好地理解潜在的问题(并希望修复它)。 glibcGNU C 库 。它是标准 C 库的实现。任何用 C 编写的程序都会使用标准库来访问文件和网络、向用户显示消息、处理进程等等。它是操作系统的基础组件。 数百个应用程序、库,甚至 Linux 系统上安装的其他非 C 编程语言都会使用 C 库。 Linux 上还有其他 C 库,例如 musl ,但 glibc 是最常见的一个。 libstdc++glibc 类似,但针对 C++:它是 C++ 标准库的实现。任何用 C++ 编写的程序都会使用它来实现 C++ 库中的事物。例如线程、流、文件、输入/输出等等。 有一个 很棒的 reddit 评论 详细介绍了这两个库之间的关系,以及它们如何与系统上的其他核心工具(如 C 编译器 (gcc) 和 binutils)相关。 标准库的一个重要方面是其 应用程序二进制接口(或 ABI)。一个在 2010 年针对 glibc 编写和编译的 C 程序应该能够在 2020 年发布的新的 glibc 版本上继续工作。为了实现这一点,glibc 提供了一个 ABI,并承诺不会改变这个特定的 ABI。glibc 可以添加额外的内容,但不会改变或删除 ABI 的任何部分。删除 ABI 中的任何内容都会破坏以前编译的应用程序。 如果 glibc 永远不能改变其 ABI,它如何改进事物呢? glibc 通过使用符号版本控制来保持 ABI 并提供新功能。glibc 提供的每个符号或函数都与一个版本相关联。链接器 (ld) 链接到带有版本的函数名。如果您的 C 程序调用函数 glob64,链接器将不仅将其链接到 glibc 中的 glob64 符号,还将链接到完全版本化的符号 glob64@GLIBC_2.27。您可以将文本 glob64@GLIBC_2.27 视为具有版本 GLIBC_2.27glob64 符号。 此功能允许旧程序使用旧但兼容的符号 glob64@GLIBC_2.2.5,而您的新程序可以利用较新的符号 glob64@GLIBC_2.27glibc 用于符号的版本通常看起来像 GLIBC_<VERSION>。一些示例是 GLIBC_2.27GLIBC_2.2.5。 您可以在这里找到有关 glibc 中符号版本控制如何工作的更多信息。 libstdc++ 具有类似的概念和实现 ABI。事实上,一些版本的 libstdc++ 甚至提供 两种不同的 ABIlibstdc++ 导出的版本通常看起来像 GLIBCXX_<VERSION>。一些示例:GLIBCXX_3.4CXXABI_1.3

这个错误是什么意思?

现在您对 C 和 C++ 标准库和符号版本有了一些了解,让我们回到错误:

app: /lib64/libc.so.6: version `GLIBC_3.1.45' not found (required by ./app)

当运行时链接器尝试为 app 加载标准 C 库(libc)时,会发生此错误。运行时链接器看到 app 依赖于一个符号,但此 C 库中未找到版本 GLIBC_3.1.45

app: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./app)

当运行时链接器尝试为 app 加载 C++ 库(libstdc++)时,会发生此错误。运行时链接器看到 app 依赖于一个符号,但此 C++ 库中未找到符号的版本 GLIBCXX_3.4.20。 换句话说,错误意味着 app 是针对较新版本的 C/C++ 库链接的。系统上可用的 C/C++ 库太旧,不提供具有这些版本的符号。

这是如何发生的?

这种类型的错误很容易遇到。

  1. 您下载了一个为较新的 Linux 发行版编译的预构建二进制文件,并尝试在较旧的 Linux 发行版上运行它。

    例如,在 RHEL 7 上运行编译为在 RHEL 8 上运行的程序时,将显示错误。同样,一个旨在在较新发行版上运行的 Python 包 也会出现这种情况。

  2. 您以某种方式 安装了为较新版本的发行版设计的发行版包

  3. 您下载了一个在您的发行版上不受支持的应用程序。

    例如,如果您尝试在 RHEL 5 上运行 .NET Core,您会遇到这个问题。

根本原因是一样的:您的操作系统与您想要运行的应用程序或库之间存在不兼容性。 您可以使用 readelf 检查应用程序或库所需的 GLIBCGLIBCXX 版本:

$ readelf --dyn-syms /usr/bin/java | grep '@GLIBC'
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (3)
     6: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (3)

在这里,您可以看到这个应用程序(java)使用了两个符号,这些符号的版本是 GLIBC_2.2.5

如何修复此错误?

修复此错误的正确方法是确保您使用的 Linux 发行版与导致此错误的应用程序(或库)兼容。 应用程序/库不支持您的 Linux 发行版: 如果您使用的是太旧且不受应用程序支持的应用程序,请升级到较新的版本。 例如,如果您需要在一个报告此错误的 RHEL 6 上运行应用程序,请考虑升级到 RHEL 7(或 RHEL 8)以解决这个问题。 应用程序/库支持您的 Linux 发行版: 如果应用程序/库支持您的 Linux 发行版的版本,那么您得到了错误的应用程序或库二进制文件。看看您是否能找到适合您的发行版的二进制下载。例如,.NET Core 支持 RHEL 6,但为 RHEL 6 提供了单独的二进制下载。常规 .NET 下载支持比 RHEL 6 更新的 Linux 发行版。 您也可能想要报告一个错误/问题或以其他方式将其报告给应用程序/库提供商。这将让他们知道他们需要更改下载部分和文档,以帮助他们的用户避免此问题。

一些关于如何修复此问题的糟糕建议

有些建议说您可以构建自己的 glibc 和/或 libstdc++ 版本并使用它们。我建议不要这样做。一旦您构建了自己的版本,您就必须负责维护构建。这也意味着要跟上所有 libc/libstdc++ 安全修复并应用它们并重新构建 libc/libstdc++。这可能适合爱好项目,但不是生产环境中的适当解决方案。 如果您确实非常了解您正在做什么,并理解了所有维护、安全和兼容性的影响,那么最后一个选项是:您可以重新构建自己的 glibclibstdc++ 版本。这里有 如何构建自己的 glibc 版本的步骤 。还有 在这里描述的运行您刚刚构建的 glibc 的更好方法 。 但话又说回来,如果您完全理解了所有的影响,您就不会阅读这篇文章来帮助理解和修复错误了。您可能已经注意到这里的一些想法并不完全正确。 还有一些建议说,从您 Linux 发行版的另一个版本中简单地获取一个 glibc 版本是可以的。这可能有效。它也可能完全破坏您的安装。它也可能阻止通过发行版的包管理器对 glibc/libstdc++ 进行任何进一步的更新。

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee