SYS_exit、sys_exit()和exit()之间有什么区别?
我的理解是:
man 2 syscalls中列出。glibc提供的那些syscall的包装函数与syscall的名称大多相似。我的问题是:例如,在man 2 syscalls中,没有提到SYS_exit和sys_exit()。他们是什么?
注意:这里的syscall exit只是一个例子。我的问题是: SYS_xxx和sys_xxx()是什么?
发布于 2013-09-24 05:50:24
我将像在您的示例中一样使用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的唯一原因是如果您正在编写内核代码。
发布于 2018-04-27 16:09:35
现在man syscall本身已经解决了这个问题,
粗略地说,属于在
__NR_xxx中定义了数字/usr/include/asm/unistd.h的系统调用的代码可以在常规sys_xxx()的Linux内核源代码中找到。( i386的调度表可以在/usr/src/linux/arch/i386/kernel/entry.S中找到。)然而,也有许多例外,主要是因为旧的系统调用被更新的系统调用所取代,而且这在某种程度上被不系统地处理了。在拥有专有操作系统仿真的平台上,如parisc、sparc、sparc64和alpha,还有许多额外的系统调用;mips64还包含完整的32位系统调用。
至少现在/usr/include/asm/unistd.h是一种预处理器黑客,它可以链接到任何一个,
/usr/include/asm/unistd_32.h/usr/include/asm/unistd_x32.h/usr/include/asm/unistd_64.hC函数exit()是用stdlib.h定义的。将此看作是一个高级事件驱动接口,它允许您向atexit()注册回调。
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered,
perform stdio cleanup, and terminate program execution with STATUS. */
extern void exit (int __status) __THROW __attribute__ ((__noreturn__));因此,内核本质上提供了一个名为__NR_xxx的接口(C符号)。传统上,人们希望sys_exit()是用预处理宏SYS_exit定义的。此宏创建sys_exit()函数。exit()函数是标准C库stdlib.h的一部分,并移植到其他完全缺乏Linux的操作系统(可能没有__NR_xxx函数),甚至可能也没有可用的sys_*函数(您可以编写exit()发送中断或在程序集中使用VDSO )。
https://stackoverflow.com/questions/18994106
复制相似问题