linux-kernel – 为什么许多系统调用(getpid)只使用strace捕获一
发布时间:2020-12-14 00:03:51 所属栏目:Linux 来源:网络整理
导读:我在程序中多次调用“getpid()”(以测试系统调用的效率),但是当我使用strace获取跟踪时,只捕获了一个getpid调用. 代码很简单: #include unistd.h#include stdio.h#include stdlib.hvoid print_usage(){ printf("Usage: program countn"); exit(-1);}int ma
我在程序中多次调用“getpid()”(以测试系统调用的效率),但是当我使用strace获取跟踪时,只捕获了一个getpid调用.
代码很简单: #include <unistd.h> #include <stdio.h> #include <stdlib.h> void print_usage(){ printf("Usage: program countn"); exit(-1); } int main(int argc,char** argv){ if(argc != 2) print_usage(); int cnt = atoi(argv[1]); int i = 0; while(i++<cnt) getpid(); return 0; } 我用gdb得到了这个: (gdb) disasse Dump of assembler code for function getpid: 0xb76faac0 <getpid+0>: mov %gs:0x4c,%edx 0xb76faac7 <getpid+7>: cmp $0x0,%edx 0xb76faaca <getpid+10>: mov %edx,%eax 0xb76faacc <getpid+12>: jle 0xb76faad0 <getpid+16> 0xb76faace <getpid+14>: repz ret 0xb76faad0 <getpid+16>: jne 0xb76faadc <getpid+28> 0xb76faad2 <getpid+18>: mov %gs:0x48,%eax 0xb76faad8 <getpid+24>: test %eax,%eax 0xb76faada <getpid+26>: jne 0xb76faace <getpid+14> 0xb76faadc <getpid+28>: mov $0x14,%eax 0xb76faae1 <getpid+33>: call *%gs:0x10 0xb76faae8 <getpid+40>: test %edx,%edx 0xb76faaea <getpid+42>: mov %eax,%ecx 0xb76faaec <getpid+44>: jne 0xb76faace <getpid+14> 0xb76faaee <getpid+46>: mov %ecx,%gs:0x48 0xb76faaf5 <getpid+53>: ret 我不太了解汇编代码.如果有人可以给出一些详细的解释也会有所帮助.根据我的观察,除了第一次getpid()调用之外,不会执行“call *%gs:0x10”(跳转到vdso),这可能是未捕获其他getpid调用的原因.但我不知道为什么. linux内核:2.6.24-29 谢谢! 解决方法
Glibc缓存结果,因为它不能在调用之间改变.例如,请参阅源代码
here.
所以真正的系统调用只执行一次.其他调用只是从缓存中读取. (代码不是很简单,因为它负责用线程做正确的事情.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |