Glibc的相关信息
2010-08-28 16:08:03 阿炯

GNU C Library 项目为 GNU 系统和 GNU/Linux 系统以及使用 Linux 作为内核的许多其他系统提供了核心库,是一个向后兼容、便携式和高性能的 ISO C 库。它被设计为可移植和高性能的 C 库,遵循所有相关标准,包括ISO C11和POSIX.1-2017,也是已知的最完善的国际化接口之一,广泛应用于 GNU/Linux 系统以及其他使用 Linux 内核的系统。glibc是gnu发布的libc库,也即c运行库;也是linux系统中最底层的api(应用程序开发接口),几乎其它任何的运行库都会倚赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现,是提供系统调用和基本函数的标准 C 语言库。主要的如下:
(1)string:字符串处理
(2)signal:信号处理
(3)dlfcn:管理共享库的动态加载
(4)direct:文件目录操作
(5)elf:共享库的动态加载器,也即interpreter
(6)iconv:不同字符集的编码转换
(7)inet:socket接口的实现
(8)intl:国际化,也即gettext的实现
(9)io
(10)linuxthreads:线程
(11)locale:本地化
(12)login:虚拟终端设备的管理,及系统的安全访问
(13)malloc:动态内存的分配与管理
(14)nis
(15)stdlib:其它基本功能

-------------------
glibc终成自由软件


GNU软件真的是纯粹的自由软件吗?并非如此。事实上每一个GNU/Linux发行版,包括Debian,在2010年8月18日之前都包括了使用非自由软件许可证的代码。这些可疑代码要上溯至1984年,GPL等自由软件许可证此时尚未诞生。

Sun为Unix创造了一个RPC实现,被称为Sun RPC。源代码使用了一个比较自由的许可证:允许任意拷贝或修改,但无权许可或分发给其它人,除非是作为用户开发的产品的一部分。Sun RPC随后被开发者广泛使用,它是NFS文件系统的基础。世事变迁:从1980年代到1990年代,自由软件运动确立了软件自由的四大原则,GPL自由软件许可证于1986年出现,Debian确定他们的核心理念是创建完全由自由软件组成的GNU/Linux发行版。Debian仔细检查了数百万行代码,他们在2002年发现旧的Sun RPC代码还存在于核心的Linux文件glibc和portmap中。但对Sun来说,寻找这些非自由的可疑代码的原始出处相当棘手,因为写代码的人已经离开了公司,但如果要改变许可证必须要确定代码的原始来源,于是此事被搁置了起来。直到8月18日,令人感到讽刺的是,收购了Sun的甲骨文公司宣布了新的许可证,用3-clause BSD许可证重新授权。现在Glibc、NFS和portmap都是纯粹的自由软件了。

-------------------
glibc创始人兼维护者辞职


GNU C library (glibc) 项目原作者兼维护者  Roland McGrath 宣布辞职和退出该项目,原因与家庭或其它问题无关,而是因为 30 年了该放手了。1980 年代,Roland 当时还是一名十多岁的青少年,他在为自由软件基金会工作期间开发了最早的  C 函数库。


在邮件列表上表示其过去几个月故意保持沉默,不回应任何邮件,看看这个项目还需不需要他这位维护者,结果证明 glibc 项目没有他仍然能继续前进,因此决定辞职和不再直接参与 glibc。2017年夏天将迎来 glibc 诞生三十周年的纪念,Roland 对所有帮助和参与 glibc 项目的人表示感谢,称有许多人对项目做出的贡献比他更大。   

glibc版本查看

$ ldd --version
ldd (GNU libc) 2.22
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

在 glibc 中,实现了很多标准,其中部分规范有:
ISO C The international standard for the C programming language.
POSIX The ISO/IEC ArrayArray45 (aka IEEE 1003) standards for operating systems.
Berkeley Unix BSD and SunOS.
SVID The System V Interface Description.
XPG The X/Open Portability Guide.


如果只需要使用 ISO C 功能,那么在编译时可以使用 -ansi 选项,glibc 实现了全部的 ISO C 功能,而 POSIX 是 ISO C 的超集,还包括了文件系统、终端设备、进程相关的函数。

Berkeley Unix 实现了前两者多数功能,源于 4.2 BSD、4.3 BSD、4.4 BSD Unix 系统(一般称为 Berkeley Unix) 以及 SunOS(基于 4.2 BSD 但是又实现了 System V 的部分功能),额外包括了符号链接、select IO 复用函数、BSD 信号函数、Socket 接口。

SVID 的全称是 System V Interface Description 描述 AT&T Unix System V operating system 的一份文档,某种意义上是 POSIX 的超集,但是没有已有的 Unix 实现了其全部功能,glibc 也仅仅实现了其部分功能,额外实现的功能包括 IPC、共享内存、hsearch、drand48、fmtmsg 以及一些其它的数学函数。

最后的 The X/Open Portability Guide, XPG 描述了什么样的系统满足类 Unix 系统的基本需要,glibc 服从该要求。

在比较新的版本中(严格来说是大于 2.10 版本)使用时要注意,需要在 CMake 类似的工具里进行判断相应的规范集。

GNU C Library 每 6 个月发布一次版本,现在又到了新版本发布的时间。GNU C Library 2.26 发布,支持 Unicode 10.0.0,2.26 带来了包括用于加快 malloc调用的 per-thread 缓存、Unicode 10.0.0 支持、DNS 存根解析器改进、对 preadv2和 pwritev2系统调用的支持,以及一些安全修复。具体改进信息可查阅发行说明


2020年08月07日,GNU C Library (Glibc) 2.32 已经发布,Glibc 是提供系统调用和基本函数的 C 库,还是每 6 个月发布一次版本。此版本更新内容包括:
支持 Unicode 13.0.0
支持 Synopsys ARC HS 内核
新的 Kurdish/Sorani 语言环境(ckb_IQ)
支持可执行文件的 ELF 部分中列出的审计模块
新的信号缩写和描述性文本函数(sigabbrev_np() 和 sigdescr_np())
针对 arm64 的分支保护安全性强化
此外还有一些 bug 修复,以及安全修复,详情查看这里

GNU C Library 2.33 已2021年2月4日发布,部分更新内容如下:
动态链接器接受 --list-tunables 参数,该参数将输出所有支持的可调参数。可通过 glibc 配置 --enable-tunables = no 禁用该参数
动态链接器接受 --argv0 参数,并提供机会更改 argv[0] 字符串
当系统功能满足使用库搜索路径中的 glibc-hwcaps 目录下的子目录要求时,动态链接器将加载共享对象的优化实现。 最初支持的子目录包括用于 powerpc64le-linux-gnu 架构的 “power9” 和 “power10”, s390x-linux-gnu 的 “z13”、“z14”、“z15” 和 “x86-64-v2”、“ x86-64-v3”, x86_64-linux-gnu 的 “x86-64-v4”。在x86_64-linux-gnu 情况下,子目录名称对应于 psABI 补充说明中定义的 独立供应商 x86-64 x86-64 微体系结构级别
动态链接器的新 --help 选项提供用法、信息和库搜索路径诊断
根据 mallinfo 添加了 mallinfo2 函数以报告统计信息
添加 <sys/platform/x86.h> 以提供 x86 CPU 功能的查询宏
对在 Linux 上运行的 RISC-V ISA 的支持已扩展到 32 位硬件。包括 rv32imac ilp32、 rv32imafdc ilp32、rv32imafdc ilp32d。32 位 RISC-V 端口至少需要Linux 5.4,GCC 7.1 和 binutils 2.28
新的 level_FORTIFY_SOURCE=3 可用。在这个级别上 glibc 可能会使用一些其他检查。目前,这些检查仅在 LLVM 9 和更高版本上可用。 目前的  GCC(10.2)不支持此级别。
不推荐使用和删除的功能,以及影响兼容性的更改
mallinfo 函数已标记为已弃用。取而代之的是 mallinfo2
在静态链接程序中使用 dlopen 时,不再加载 HWCAP 子目录的备用实现,而是使用默认实现
不建议使用 <sys/vtimes.h> 头文件,并且函数 vtimes 已被删除。为了支持旧的二进制文件,vtimes 函数作为兼容性符号继续存在。应用程序应使用getrlimit 或 prlimit

详细内容请查看更新公告

GNU C Library 2.34 已于2021年8月初发布,部分更新内容如下:
所有以前在 libpthread、libdl、libutil 和 libanl 中实现的功能都被整合到 libc 库本身。官方仍然提供了这些 former libraries 的空静态存档,以便在应用程序向前推进时不至于出现太多破坏性的变化,只需要与 libc 链接。
在 32 位 x86 等配置上支持 64 位 time_t。目前,Time_t 在这类配置上仍默认为 32 位,但将来可能会改变。
在 Linux 上有一个新的 Glibc tunable,允许配置线程栈缓存的大小。
添加了_Fork 作为 async-signal-safe fork replacement。
在 Linux 上支持 close_range 函数,当在现代版本的 Linux 内核上运行时,可以有效地关闭一系列的文件描述符。
支持现代 CPU 功能(如 Arm SVE)的 dynamic sized register sets。
支持 ISO C2X function timespec_getres。
更多有用的 linker diagnostics。
以及一些安全修复和其他错误修复。

详细内容可查看更新公告。  

时隔 15 年Glibc终于引入了用于 Linux 的 arc4random 函数

2022年7月下旬的一个提交显示,GNU C 库 (Glibc) 终于添加了用于 Linux 的 arc4random 函数。在 BSD 上, arc4random、arc4random_buf 和 arc4random_uniform 函数很常见,它可以提供比 rand/random 高质量的随机数生成。反观 Glibc,早在 2007 年就有人在 Bug 4417 中请求使用 Glibc 的 arc4random,并提供了 实现 arc4random 的初步补丁。但该 arc4random 补丁得到的回应却是 “ glibc 不是啥代码都可以随便放的垃圾场 ”。而在 2018 年,一位红帽工程师再度为 Glibc 开发 arc4random。四年后,Linaro 的 Adhemerval Zanella Netto 成功地将 arc4random 系列函数通过终点线并进入了 Glibc 的主线。其主要优点是随机性的单位不是统一随机变量(uint32_t),而是一个随机位。它最初使用 32 位随机变量,然后逐字节采样来优化内部缓冲区采样。根据请求的上限,它可能会导致更好的 CPU 利用率。另据外媒 Phoronix 报道,除了将 arc4random、arc4random_buf 和 arc4random_uniform 函数添加到标准库之外,其它补丁活动还为 AArch64、x86 SSE2、x86 AVX2、PowerPC64 和 s390x 添加了优化的 ChaCha20 版本。

GNU C Library 2.36 版本已经于2022年8月上旬发布,主要内容如下:
添加了对 DT_RELR 相对重定位格式的支持,一个新的 ELF 动态标签。
在 Linux 上添加 pidfd_open、pidfd_getfd 和 pidfd_send_signal 函数。pidfd 功能提供了对进程的访问,同时避免了传统 Unix 系统上的 PID 重用问题。
在 Linux 上增加了 process_madvise 函数。它具有与 madvise 相同的功能,但会更改 pidfd 标识的目标进程。
在 Linux 上增加了 process_mrelease 函数。它允许调用者释放垂死进程的内存。
添加了 “no-aaaa” DNS 存根解析器选项。可使用它来抑制存根解析器进行的 AAAA 查询,包括由基于 NSS 的接口(如 getaddrinfo)触发的 AAAA 查找。
在 Linux 上添加 fsopen、fsmount、move_mount、fsconfig、fspick、open_tre 和 mount_setattr。它们是新的 Linux 内核挂载 API 的一部分,允许应用程序更灵活地配置和操作文件系统挂载。
localedef 现在接受以 UTF-8 编码的语言环境定义文件。以前,不在 ASCII 范围内的输入字节会导致不可预测的输出。
添加了函数 arc4random、arc4random_buf 和 arc4random_uniform ,产生更高质量的随机性。
添加了对在 Linux 上运行 LoongArch 的支持,至少需要 binutils 2.38、GCC 12 和 Linux 5.19。
更多内容可查看更新说明

Glibc 获得 AVX-512 优化,部分函数周期减少约 30%

2022年10月下旬消息,GNU C 库 “glibc” 获得另一轮 AVX-512  优化工作,使用英特尔的 AVX-512 处理器或 AMD Zen 4 的用户可从中受益。AVX-512 是一种 SIMD 指令,用于在执行特定任务时提高 CPU 的性能。英特尔工程师 Sunil K Pandey 为 Glibc 开发了增强型矢量扩展 EVEX512 版本的 memchr、rawmemchr 和 wmemchr 函数,memchr、rawmemchr 和 wmemchr 函数变体用于在内存块中定位字符。与标准 EVEX 实现相比,这些字符串函数的 EVEX512 版本可减少多达 30% 的函数周期,使用 512 位向量的好处因字符串长度和其他因素而异。与此同时,今天在 Glibc git 中,Noah Goldstein 对各种 libc 函数的现有 EVEX 实现进行了许多优化。

Glibc 2.37 已经于2023年2月上旬发布发布,Glibc 是提供系统调用和基本函数的标准 C 语言库,在 Linux 和其他平台上广泛使用的 libc 实现有许多错误修复以及一些新功能及数十个不同的错误修复。一些亮点包括:
getent 工具现在支持 --no-addrconfig 选项。
动态链接器不再从库搜索路径上的 “tls” 子目录或与 AT_PLATFORM 系统名称对应的子目录加载共享对象。
CVE-2022-39046 的安全修复,当向 syslog 函数传递一个长度超过 1024 字节的特制输入字符串时,它可以从堆中读取未初始化的内存。

Glibc 2.38 已于2023年8月上旬发布,部分更新内容如下:
围绕 C2X 功能的持续支持。
使用 GNU Binutils 2.40+ 和 GCC 13+ 时,添加了对在 GNU Hurd 上运行的 x86_64 的支持。
添加了源自 OpenBSD 的 strlcpy 和 strlca t 函数,预计将出现在未来的 POSIX 版本中。
新的 “--enable-fortify-source” 配置选项。
新增了 glibc.pthread.stack_hugetlb 可调整项,用于在 pthread_create 时禁用堆栈分配中的 Transparent Hugepages (THP)。
修复了各种错误,并至少修复了一个安全问题。
更多详情可查看更新公告

Glibc 2.39 已于2024年1月下旬发布,此版本带来了多项新功能、安全修复和其他增强功能,包括与 x86 shadow-stack 机制的集成、用于控制 groups 的几个新 posix_spawn () 变体、pidfd_spawn () 和 pidfd_spawnp ()、C2X stdbit.h header、移除 libcrypt 库等。一些亮点包括:
x86-64 系统上的新增可调整项 “glibc.cpu.plt_rewrite”,可启用 PLT rewrite,以便使用直接分支重写 PLT 中的间接分支。
现在内核支持已全部就绪,与 Linux 6.6+ 内核中的 Shadow Stack 接口同步。
为 Linux 添加了函数 posix_spawnattr_getcgroup_np 和 posix_spawnattr_setcgroup_np,以便以 race-free 的方式在新进程中设置 cgroup v2。
Linux 的 pidfd_spawn 和 pidfd_swap 函数与 posix_spawn 类似,但返回文件描述符而不是进程 ID。为此,还添加了 pidfd_getpid 用于从进程文件描述符获取进程 ID。
stdbit.h header 已从 ISO C2X 添加。
Libcrypt 已从 GNU C 库中删除,用户应改用 libxcrypt。
IA-64 Linux 配置不再受支持,因为 Itanium 支持已从 Linux 内核中删除。
各种安全修复,包括本地权限升级问题;以及许多错误修复。
更多详细信息可参阅发行公告


该文章最后由 阿炯 于 2024-02-01 17:25:17 更新,目前是第 2 版。