0

如何在运行时提取和比较具有以下限制的 libc 版本?

  • 稳定的解决方案(命令输出解析被丢弃,因为这可能会有所不同)
  • 不应依赖执行外部工具,如 ldd、gcc 或其他
  • 必须在静态链接的二进制文件 (AppRun) 上工作
  • 将在 C 中实现

语境:

在 AppImage 项目中,一直在开发一项功能,以允许创建向后兼容的包。为此,我们创建了一个名为 AppRun 的程序。Things 程序将系统 glibc 版本与捆绑包中的版本进行比较,并将捆绑包配置为在运行时使用较新的版本。该程序是静态链接的,不应依赖外部工具。

现在我们扫描libc.so文件以查找GLIBC_X.XX并存储更大的。但这不再适用于 Ubuntu 20.04 中的最新二进制文件。二进制文件是 2.31,但文件中没有GLIBC_2.31字符串,因此该方法失败。

相关问题:

4

2 回答 2

1

该程序将系统 glibc 版本与捆绑包中的版本进行比较,并将捆绑包配置为在运行时使用较新的版本。

libc.so.6请注意,正如这个答案所解释的,“在运行时配置”不仅仅是将程序指向“正确” 。

现在我们扫描 libc.so 文件中是否出现 GLIBC_X.XX 并存储更大的。但这不再适用于 Ubuntu 20.04 中的最新二进制文件。

您似乎对符号版本控制的工作方式有一个基本的误解。这个答案可能有助于更好地理解这一点。

你的方法奏效了

二进制文件是 2.31,但文件中没有 GLIBC_2.31 字符串,因此该方法失败。

正如上面引用的答案所解释的,这意味着 GLIBC-2.31 没有引入任何新的 ABI 不兼容符号,并且与该版本的 GLIBC 链接的程序将在运行时存在较旧的 GLIBC 版本时工作(但可能会遇到 GLIBC 之间修复的错误版本 2.30 和 2.31 等)。

于 2022-02-12T17:53:45.253 回答
0

libc 版本

有 glibc 的替代品。

现在我们扫描 libc.so 文件中是否出现 GLIBC_X.XX

搜索 glibc 打印的字符串 - GNU C Library <pkg+release_name> release version <version>[,.]...,且 version 有 format [0-9]+\.[0-9]+(\.[0-9]+)?

只需libc.so.6/etc/ld.so.cache.

在 C 中执行此操作:

libcfile="$(grep -azm1 '/libc.so.6$' /etc/ld.so.cache | tr -d '\0')"
grep -aoP 'GNU C Library [^\n]* release version \K[0-9]*.[0-9]*' "$libcfile"

查看提交,这应该永远有效:
https://github.com/bminor/glibc/blame/b7eb84454020c59d528e826ae1889f411ed69e26/version.c#L28
https://github.com/bminor/glibc/blame/9f70e81bcaa12b0673cd0879d6f4a21ad6dddce5/version.c #L28
https://github.com/bminor/glibc/blame/92e4b6a92716f8b2457376291171a6330d072b0d/csu/version.c#L27
https://github.com/bminor/glibc/blame/50c66c7acd90f257b295e58bf938ed120cbc227c
https: //github.com/bminor/glibc/blame/b92a49359f33a461db080a33940d73f47c756126/csu/version.c#L27

似乎可以在我能找到的 docker 中最古老的 ubuntu 上工作:

$ cmd='grep -aoP "GNU C Library [^\n]* release version \K[0-9]*.[0-9]*" "$(grep -azm1 "/libc.so.6$" /etc/ld.so.cache | tr -d "\0")"'
$ echo -n 'local: '; sh -c "$cmd"; for i in 13.04 16.04 14.04 22.04 21.10 20.04 18.04; do echo -n "ubuntu:$i "; docker run -ti --rm ubuntu:$i sh -c "$cmd"; done
local: 2.33
ubuntu:13.04 2.17
ubuntu:16.04 2.23
ubuntu:14.04 2.19
ubuntu:22.04 2.34
ubuntu:21.10 2.34
ubuntu:20.04 2.31
ubuntu:18.04 2.27

我还用 glibc2.15 测试了 opensuse12.2,在那里libc.so.6打印GNU C Library stable release version 2.15 (20120628), by Roland McGrath et al.

于 2022-02-10T21:02:54.993 回答