arm64大约支持280个系统调用,我们平时使用的这些系统调用,到底工作原理是什么,调用后又是到哪里实现的呢,这篇文章初步了解下内核系统调用的流程,并告诉跟踪这个流程的方法 。
文章插图
废话不多说,如上就是linux的系统调用关系图:
1.绝大部分用户态系统调用接口,都经过glibc库,最终到内核是sys_xx实现函数完成功能并返回用户态;
2.少量glibc不支持的API可通过其他方式直接到内核sys_xx实现函数完成功能并返回用户态;
3.存在少量系统调用glibc内部实现,但是实现流程使用内核关键函数,比如malloc;
举例说明如何跟踪open()函数
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>void mAIn(){open("xx", O_CREAT);}
以上是open的系统调用 , 可以使用gcc open.c -o open命令编译成二进制 。ldd openlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53081a5000)
从上可知最终到系统libc库查看libc库的open:nm -D /lib/x86_64-linux-gnu/libc.so.6|grep open00000000000f7030 W open00000000000f7030 W __open
接下来需要下载glibc库的源码,然后git checkout glibc-2.9vim io/open.cint__open (file, oflag)const char *file;int oflag;{int mode;if (file == NULL){__set_errno (EINVAL);return -1;}if (oflag & O_CREAT){va_list arg;va_start(arg, oflag);mode = va_arg(arg, int);va_end(arg);}__set_errno (ENOSYS);return -1;}
如何glibc库经过初步的参数检查,会调用到内核的系统调用sys_open() ->include/linux/syscalls.h ->sys_open -> do_sys_open ->fs/open.c ->long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)系统调用 malloc
cat test.c#include <stdio.h>#include <malloc.h>void main(){void *c = (void*)malloc(10);free(c);}
【linux的系统调用执行探究】如上ldd testlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53081a5000)nm -D /lib/x86_64-linux-gnu/libc.so.6|grep malloc0000000000084130 T __libc_malloc0000000000084130 T malloc
glibc源码中find . -name malloc.c./malloc/malloc.c
推荐阅读
- 深度优化数据库性能:Linux 内核参数调整解析
- Nacos配置中心的Pull原理,附源码
- 如何提高python程序代码的健壮性
- C++中函数参数的优秀传递方式
- 每个开发者都应该知道的七个原则
- 解析Java中的跨域请求问题与解决方案
- 使用Java构建云原生监控与日志系统
- 纤程与协程的区别
- 带你吃透Kafka的可靠性设计
- 前端框架的演进与未来展望