Linux系统调用 - 进程管理初探(上)

  本文对Linux系统调用的机制进行了大致分析,并以此为基础对Linux进程管理(多进程调用、进程同步等)进行初步探索。在研究进程fork()函数的过程中,笔者产生了很多问题,也通过查阅资料、动手实验等方式对这些问题有了一定的研究和理解。本文将按照笔者对问题研究的历程入手,对Linux进程管理的部分基本过程和背后机理进行阐述。

在本文中,你将看到:

  • 系统调用(system call)的流程
  • POSIX基本进程管理函数——fork() / vfork() / clone() / wait() / waitpid()
    • fork()vfork()的区别、发展
    • vfork()等待机制(Completion 进程同步机制)
    • wait()函数等待机制(详解)

Linux 系统调用(system call)

Introduction

​ System Call (syscall),是运行在操作系统上的用户程序调用系统功能的方式。为了安全,用户程序在运行时处于用户态,不能调用系统内核函数,也不能访问属于操作系统的内存空间。那么,用户程序如何使用操作系统提供的功能?答案是:使用系统调用

  系统调用与API不同,后者定义了一些系统功能调用的接口(函数原型),而前者通过中断向内核发出功能请求。标准库和硬件兼容标准库定义了一部分API,为用户程序提供系统调用服务,而这些API后的封装函数通过系统调用请求系统的资源和功能。

  以Linux为例,其glibc库函数实现了一些POSIX标准指定的API,如mallocfree等,也实现了标准库函数printf等,这些函数内部都使用系统调用来请求系统实现对应功能,前两个函数都使用brk系统调用来控制进程堆的大小,printf则使用了write系统调用来向控制台打印信息。

Procedure

从用户程序开始,使用一个系统调用并返回的流程如下(以printf举例):

  • 用户调用printf,完成参数传递。

    printf("Hello, %s.\n", name);
    
  • glibc完成参数解析,填充write()调用需要的参数,并触发软中断(汇编):

    handle_args();  // 处理传入参数
    prepare_args_for_write();  // 为调用write配置参数
    int 0x80;	// 使用系统中断
    
    • 其中,从prepare_args_for_write()开始,程序使用汇编语言编写,配置参数通常为:给对应的寄存器赋值,或是将参数压入栈中。
  • 系统调用处理程序(system call handler):识别并处理软中断,并转由对应的 系统调用服务例程(system call service routine)处理。

  • 系统调用服务例程(system call service routine)一般为C语言程序,处理系统调用后将返回值返还给用户进程。

Detail

进入系统调用

系统调用一般通过两种方式进入,且都为汇编语言指令。以下两个指令的功能相同:

int 0x80;
syscall;
  • 第一条指令能在x86x64平台上使用,但第二条指令只有x64支持。
  • 两个指令的机器码完全不同,(这给x64架构上的ROP攻击提供了更多的机会XD)

不同的系统调用通过系统调用号进行区分,它被置于eax/rax寄存器上,下面是几个常用的系统调用:

NRsyscall name
0read
1write
2open
12brk
59execve
  • 如果需要参数,它们一般被保存在寄存器中,顺序一般为rdi rsi rdx
退出系统调用

内核仍然通过汇编语言指令从系统调用中退出,CPU切换回用户态,继续执行用户程序

iret;
sysexit;
  • 就像函数拥有返回值,一般系统调用也有返回值,在返回前,系统将值保存在eax中,并返回给用户进程。
兼容性问题

  为了同时支持两种系统调用方式,libc库需要使用特殊的兼容方法。在程序初始化时,它会创建一个较小的ELF共享对象,这个对象将被映射到用户进程的地址空间中。它将一个最有效的系统调用方式定义在__kernel_vsyscall函数中,所有系统调用都转而执行此函数,此函数使用系统和内核支持的系统调用方式进行系统调用。


Others

下部分,我们将探究Linux进程管理相关的函数以及背后的机理。

参考资料:《深入理解Linux内核》、Linux man page

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值