加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

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
gcc(GCC)4.2.4
libc 2.7,

谢谢!

解决方法

Glibc缓存结果,因为它不能在调用之间改变.例如,请参阅源代码 here.

所以真正的系统调用只执行一次.其他调用只是从缓存中读取. (代码不是很简单,因为它负责用线程做正确的事情.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读