SYS_exit、sys_exit() 和 exit() 之间有什么区别?
我的理解是:
- Linux内核提供了系统调用,这些调用在
man 2 syscalls
.
- 这些系统调用的包装函数由
glibc
它们的名称与系统调用大多相似。
我的问题:在man 2 syscalls
例如,没有提及 SYS_exit 和 sys_exit()。这些是什么?
注意:系统调用exit
这里仅举一个例子。我的问题实际上是:什么是 SYS_xxx 和 sys_xxx()?
我将在您的示例中使用 exit() ,尽管这适用于所有系统调用。
sys_exit() 形式的函数是内核例程的实际入口点,该例程实现了您认为是 exit() 的函数。这些符号甚至对于用户模式程序员来说是不可用的。也就是说,除非您正在破解内核,否则您无法链接到这些函数,因为它们的符号在内核外部不可用。如果我写了 libmsw.a ,它有一个文件范围函数,例如
static int msw_func() {}
如果在其中定义,您将无法成功链接到它,因为它未在 libmsw 符号表中导出;那是:
cc your_program.c libmsw.a
会产生如下错误:
ld: cannot resolve symbol msw_func
因为它没有出口;这同样适用于内核中包含的 sys_exit() 。
为了让用户程序访问内核例程,需要使用 syscall(2) 接口来实现从用户模式到内核模式的切换。当模式切换(有时称为陷阱)发生时,将使用一个小整数在将整数映射到内核函数的内核表中查找正确的内核例程。表中的条目具有以下形式
{SYS_exit, sys_exit},
其中 SYS_exit 是一个预处理器宏,它是
#define SYS_exit (1)
从你出生之前起就一直是 1,因为没有理由改变它。它也恰好是系统调用表中的第一个条目,可以查找简单的数组索引。
正如您在问题中所指出的,常规用户模式程序访问 sys_exit 的正确方法是通过 glibc (或类似的核心库)中的瘦包装器。您需要搞乱 SYS_exit 或 sys_exit 的唯一原因是您正在编写内核代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)