系统调用 - syscall

2020-02-18  本文已影响0人  写个代码容易么

linux系统调用是通过中断实现的,软中断指令int发起中断信号。
linux只占用一个中断向量号,即:0x80。
系统调用前,linux在eax寄存器中写入子功能号,中断处理程序根据eax寄存器的值来判断用户进程申请哪种系统调用。

syscall 是一个库函数

man syscall

NAME
       syscall - indirect system call 间接系统调用

SYNOPSIS
       #define _GNU_SOURCE         /* See feature_test_macros(7) */
       #include <unistd.h>
       #include <sys/syscall.h>   /* For SYS_xxx definitions */

       函数原型:syscall(子功能号,可变参数);
       long syscall(long number, ...);

DESCRIPTION
       syscall()  is  a  small  library  function  that  invokes  the  system call whose assembly language interface has the specified number with the specified arguments.  
       syscall是一个通过特定子功能号和特定参数调用汇编语言接口的库函数。

       Employing syscall() is useful, for example, when invoking a system call that has no wrapper function in the C library.
       可直接通过syscall直接调用C库中未封装的函数。

       syscall() saves CPU registers before making the system call, restores the registers upon return from the system call, and stores any error code returned by the system call in errno(3) if an error occurs.
       系统调用执行前先保存CPU寄存器的值,系统调用返回后还原寄存器并将系统调用错误码存储在errno中(errno - number of last error)。

       Symbolic constants for system call numbers can be found in the header file <sys/syscall.h>.
       系统调用的符号常量在sys/syscall.h头文件中。

实例1

调用glibc中不提供的函数,如获取线程内核id

gettid函数文档如下,文档明确指出Glibc不提供该函数封装,所以我们需要自己通过syscall封装该函数。

man gettid


NAME
       gettid - get thread identification

SYNOPSIS
       #include <sys/types.h>

       pid_t gettid(void);

       Note: There is no glibc wrapper for this system call; see NOTES.
NOTES
       Glibc does not provide a wrapper for this system call; call it using syscall(2).

       The thread ID returned by this call is not the same thing as a POSIX thread ID (i.e., the opaque value returned by pthread_self(3)).

       In a new thread group created by a clone(2) call that does not specify the CLONE_THREAD flag (or, equivalently, a new process created by fork(2)), the new process is a  thread
       group leader, and its thread group ID (the value returned by getpid(2)) is the same as its thread ID (the value returned by gettid()).

通过syscall实现gettid函数如下:

pid_t gettid() {
    pid_t tid;
    tid = syscall(SYS_gettid);
    return tid;
}

该函数输出的线程id与top -H -p <pid>命令查看的id一致

中断

系统中断分两种:硬件中断和软中断
硬件中断:来自于硬件异常或事件发生,如键盘按下。
软中断:一条指令,带一个中断号,如Linux下int 0x80为系统调用中断。

操作系统中断处理流程:

中断处理.png

Linux系统调用执行流程:

Linux系统调用.png
上一篇下一篇

猜你喜欢

热点阅读