系统调用:sys_exit(),SYS_exit和exit()之间的区别

Gra*_*ent 7 linux kernel system-calls

SYS_exit,sys_exit()和exit()有什么区别?

我的理解:

  • linux内核提供系统调用,列在man 2 syscalls.
  • 这些系统调用提供的包装函数与syscalls的glibc名称大致相似.

我的问题:在man 2 syscalls,例如,没有提到SYS_exit和sys_exit().这些是什么?

注意:exit这里的系统调用只是一个例子.我的问题是:什么是SYS_xxx和sys_xxx()?

msw*_*msw 3

我将在您的示例中使用 exit() ,尽管这适用于所有系统调用。

sys_exit() 形式的函数是内核例程的实际入口点,该例程实现了您认为是 exit() 的函数。这些符号甚至对于用户模式程序员来说是不可用的。也就是说,除非您正在破解内核,否则您无法链接到这些函数,因为它们的符号在内核外部不可用。如果我写了 libmsw.a ,它有一个文件范围函数,例如

static int msw_func() {}
Run Code Online (Sandbox Code Playgroud)

如果在其中定义,您将无法成功链接到它,因为它未在 libmsw 符号表中导出;那是:

cc your_program.c libmsw.a
Run Code Online (Sandbox Code Playgroud)

会产生如下错误:

ld: cannot resolve symbol msw_func
Run Code Online (Sandbox Code Playgroud)

因为它没有出口;这同样适用于内核中包含的 sys_exit() 。

为了让用户程序访问内核例程,需要使用 syscall(2) 接口来实现从用户模式到内核模式的切换。当模式切换(有时称为陷阱)发生时,将使用一个小整数在将整数映射到内核函数的内核表中查找正确的内核例程。表中的条目具有以下形式

{SYS_exit, sys_exit},
Run Code Online (Sandbox Code Playgroud)

其中 SYS_exit 是一个预处理器宏,它是

#define SYS_exit (1)
Run Code Online (Sandbox Code Playgroud)

从你出生之前起就一直是 1,因为没有理由改变它。它也恰好是系统调用表中的第一个条目,可以查找简单的数组索引。

正如您在问题中所指出的,常规用户模式程序访问 sys_exit 的正确方法是通过 glibc (或类似的核心库)中的瘦包装器。您需要搞乱 SYS_exit 或 sys_exit 的唯一原因是您正在编写内核代码。