Linux下C库函数到系统调用函数到内核函数调用的过程
  egV2hvewum2o 2023年11月02日 100 0


当我们在shell写入一个程序的时候

#include <stdio.h>

此处调用了stdio.h的C标准库,他是存在在glibc中的库函数,他里面通过一些预处理最终会调用系统调用函数,其中,系统调用函数一般是放在

#include <unistd.h>

当然,我们也可以直接写一个系统调用函数调用内核函数

ssize_t write(int fd, const void *buf, size_t count);
/*************************************************************************
> File Name: hello.c
> Author: liuhao
> Mail: 2226958871@qq.com
> Created Time: Sat 19 Jun 2021 11:02:59 AM CST
************************************************************************/

#include<stdio.h>
#include <unistd.h>
int main() {
printf("Hello World\n");
write(1, "Hello World\n", 20);
return 0;
}
➜  C ./a.out
Hello World
Hello World

以write为例,系统调用函数和内核函数有一个接口来调用内核函数sys_write,该方法会直接调用硬件(比如write,会直接写入到屏幕上进行显示)

  • open: 打开文件或设备
  • read: 从打开的文件或设备中读取数据
  • write: 向打开的文件或设备中写入数据
  • close:关闭文件或者设备
  • ioctl:把控制信息传递给设备驱动文件

具体执行讲解可见​​ELF可执行文件执行全过程​​

strace ./a.out
execve("./a.out", ["./a.out"], 0x7fffc106e0d0 /* 27 vars */) = 0
brk(NULL) = 0x564fe1e53000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff87737bd0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=102952, ...}) = 0
mmap(NULL, 102952, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0272e45000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0272e43000
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0272c51000
mprotect(0x7f0272c76000, 1847296, PROT_NONE) = 0
mmap(0x7f0272c76000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f0272c76000
mmap(0x7f0272dee000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7f0272dee000
mmap(0x7f0272e39000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f0272e39000
mmap(0x7f0272e3f000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0272e3f000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f0272e44540) = 0
mprotect(0x7f0272e39000, 12288, PROT_READ) = 0
mprotect(0x564fe0654000, 4096, PROT_READ) = 0
mprotect(0x7f0272e8c000, 4096, PROT_READ) = 0
munmap(0x7f0272e45000, 102952) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
brk(NULL) = 0x564fe1e53000
brk(0x564fe1e74000) = 0x564fe1e74000
write(1, "Hello World\n", 12Hello World
) = 12
exit_group(0) = ?
+++ exited with 0 +++

其中的第一个系统调用函数execve

int execve(const char *pathname, char *const argv[], char *const envp[]);

进入内核态执行sys_execve检查argv和envp、do_execve读入目标镜像文件、search_binary_handler搜索处理该二进制文件的队列、load_elf_binary检查elf文件架构并分配内存、没有动态链接库直接执行/有动态链接库进行链接write,_再次进入系统调用sys_write、把字符串写到屏幕上的进程进行等待、执行程序


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  4WdcduV19eWs   2023年11月02日   64   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   62   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   66   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   53   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   42   0   0 ios#includeios#include
  ZydNzX6XOBO2   2023年11月02日   110   0   0 出队C++ci#include
  4WdcduV19eWs   2023年11月02日   65   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   88   0   0 ios#includeios#include
  ZydNzX6XOBO2   2023年11月02日   50   0   0 i++C语言#include
  4WdcduV19eWs   2023年11月02日   51   0   0 ios#includeios#include
  4WdcduV19eWs   2023年11月02日   78   0   0 #includelinuxlinux#include
egV2hvewum2o