标准C库和系统调用如何协同工作?

5

最近我对编译器、标准库和内核的内部工作方式很感兴趣。当我在寻找标准C库的源代码时,我发现了Glibc。但是在Glibc官方网站上所说的是:该库定义了“系统调用”和其他基本功能,如open、malloc、printf、exit...

因此,我猜想Glibc实际上并没有提供标准C库的源代码,而是为这些函数提供系统调用,然后由内核来处理,我是对的吗?

我想了解更多关于这些内容的知识。例如,在 C 程序中,sinprintfstrlen 函数是如何执行的?如果 Glibc 只提供系统调用,那么这些函数的实际源代码在哪里?内核如何执行它们?可以在哪里找到执行这些函数的内核部分的源代码?


glibc的源代码用于构建glibc库。编译器将源代码转换为可执行代码。 - Vaughn Cato
你知道.so.a文件吗? - Mike
是的,我知道.so和.a文件。 - user1726549
3个回答

6

C库是一个用户空间的库,几乎像任何其他库一样。

系统调用是由内核提供的接口。它们与C标准无关,是特定于操作系统的。虽然UNIX类似的操作系统之间存在一些相似之处,但那是另一个话题。

C库中实现的某些函数最终会以某种方式调用系统调用。但这与任何其他库都是一样的。

我建议查看OpenBSD的C库。Android手机也使用它。它简单、清晰并且文档非常好。您可以在这里找到它。


1
声称Android手机使用OpenBSD C库有些牵强,尽管在Android上使用的Bionic C库确实包含了来自3个主要*BSD的代码。 - nos
我同意 @nos 的观点,需要注意的是Android使用Bionic libc,这是一个混合版本... - Mike
只需查看官方存储库中大多数文件的 CVS 标头。例如:https://github.com/android/platform_bionic/tree/master/libc/stdlib - Paul Irofti

1

Glibc提供了库函数的代码,并提供了系统调用定义。提供的函数中只有很小一部分是真正的系统调用。其他函数的代码嵌入在库中,要么在内部完成所有工作,要么通过内部调用将其委托给内核。您可以查看各种libc源以了解它们的工作原理。 Glibc、Eglibc、Newlib、Dietlibc等源代码都可以供您使用。

尽管可能存在将任何libc调用都与系统调用相关联的操作系统,但出于许多原因,这并不常见。


0
您可以在this page中了解系统调用的感觉。它有点陈旧,但可以让您了解实现调用的内核文件的指针和想法。在典型的 Unix 系统中,有低百个系统调用。例如,您可以查看 sys_open 或 sys_write。当您查看类似 fopen 或 open 的调用时,最终它们都映射到 sys_open。像 printf 或 write 这样的东西映射到 sys_write。
内核介质处理诸如对文件的访问之类的事情,因此需要成为一个瓶颈,但是库通过将这些调用包装在有帮助的抽象中使其更容易访问,通常会为给定的系统调用提供多个抽象。库本身不提供系统调用,它设置事物,然后陷入内核,内核实现它们。系统调用实际上是 libc 程序针对内核 API。
一些调用(例如 strlen)根本不需要内核访问,该调用只需要查看已经分配的内存即可。
一个很好的从用户空间探索这个问题的工具是strace。给定一个程序,它将显示程序所做的所有系统调用。您可以使用它来分析libc调用如何映射到系统调用。

我觉得楼主在寻找你发布的链接中应该包含在第二部分的内容。可惜它还没有准备好。 - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接