【发布时间】:2018-02-13 12:37:59
【问题描述】:
我有几个假设,很可能其中一些是不正确的。请纠正我哪里错了。
我们可以对用 C 编写的程序中的函数进行如下分类:
- 发送到动态加载的库的函数:
- 这些被发送到将它们转换为多个标准 C 函数的库
- 库将它们传递给 libc,在那里它们被转换为多个系统调用。
- Libc 将这些传递到内核并在其中执行它们,并将返回值发送回 libc。
- Libc 将收集返回值,将它们按 c 函数分组,并使用它们为每个 c 函数创建 1 个返回值。这些返回将被发送回动态加载的库。
- 此库将收集所有退货并使用它们创建 1 个退货,然后将其发送回原始程序。
- 在代码中或静态编译库的一部分中定义的函数:一切都与上述类别相同,但:
- 他们的程序已经将它们转换为已知的标准 C 函数,或者在另一种情况下转换为调用动态加载的库的函数。
- 标准 c 函数被发送到 libc,其他函数被发送到动态加载的库(它们将按上述方式处理)。
- 程序将根据两种函数的返回创建 1 个最终返回
-
作为标准 C 函数的函数:它们只会被发送到 libc,libc 将以与上述相同的方式与内核通信,并且将向程序发送 1 个返回
-
作为系统调用的函数:它们不会直接发送到内核,而是必须传递给 libc,尽管它不会做任何额外的工作。
安全检查(权限、写入未分配的内存,...)总是由内核完成,尽管 libc 和上面的库也可能首先检查它。
所有符合 POSIX 的系统都遵循这些规则
【问题讨论】:
-
有两个关键区别:(1)用户模式和内核模式之间是否存在转换(在我看来,系统调用的关键定义)和(2)是否不是被调用函数位于动态链接(共享)或静态链接库中。几乎所有其他事情都由此而来。也许还有一个区别(3)被调用的函数是“程序的一部分”还是“其他人的库”。也许还有一个区别(4)是否涉及vDSO。
-
作为系统调用的函数 这在术语上是矛盾的。函数就是函数,系统调用就是系统调用。一些函数比其他函数更接近于系统调用 - 由于更改了
*at()接口,例如openat(),它可能没有你想象的那么接近。我不确定为什么在 C 中“函数”和“系统调用”之间存在这种区别。如果您正在编写 C,那么您正在使用函数。您几乎需要直接汇编程序来执行实际的系统调用。 -
这是对事物进行分类的一个很好的尝试……但这是一个糟糕的问题。它从“不清楚你在问什么”(帖子中没有
?)到“太宽泛”(Please correct me where they are wrong.用于许多陈述)不等。您在标题中有一个确切的问题 - 发布问题是为了详细说明该问题,而不是介绍许多其他内容。
标签: c linux linux-kernel posix libc