背景
最近,在看unix环境高级编程,第一章就讲了unix下的函数调用结构:
这图其实把结构表达的很清楚,但感觉还是有两个疑问:
- 库函数是具体是如何调用system call
- 不通过库函数,我们程序中如何调用system call
追溯
既然要探究库函数本质,那必然得看看库函数的源码,以最新版本的glibc 2.27为例吧
本来之前想从fgets入手的,但整个文件结构实在太大,库函数里面做了不少的处理,还是直接从fork函数入手
看到文件最后有:
可以发现fork被定义到了__libc_fork,看看__libc_fork函数里面并不是像我们想象的那样,直接调用的system call,其库函数里面自身做了一些优化工作,但可以观察到这一句:
INLINE_SYSCALL (fork, 0)
,字面上看应该就是系统调用了,继续进去再看:指向了
INLINE_SYSCALL1
,继续进去跳到了
inline_syscall0
,再看这下终于看到了最终的调用方式,其是通过汇编
callsys
来进行系统调用的。到此,其实两个问题也得到了回答:可以通过汇编来实现直接进行系统调用。
总结
其实就验证了库函数与系统调用的关系,要注意的是,目前的glibc太大了,要查找调用关系,其实还挺麻烦的,即使用source insight,搜索也会产生大量的匹配信息,可能还是用libc初始版本比较方便吧