续x86_64进程内存空间布局-vDSO

在上一篇Linux x86_64进程内存空间布局中谈了两个不同参数下的进程运行时内存空间宏观的分布。也许你会注意到这样一个细节,在每个进程的stack以上的地址中,有一段动态变化的映射地址段,比如下面这个进程,映射到vdso。

技术分享

如果我们用ldd看相应的程序,会发现vdso在磁盘上没有对应的so文件。
不记得曾经在哪里看到大概这样一个问题:

getpid,gettimeofday是不是系统调用?

其实这个问题的答案就和vDSO有关,杂x86_64和i386上,getpid是系统调用,而gettimeofday不是。


vDSO全称是virtual dynamic shared object,是一种内核将一些本身应该是系统调用的直接映射到用户空间,这样对于一些使用比较频繁的系统调用,直接在用户空间调用可以节省开销。如果想详细了解,可以参考这篇文档


下面我们用一段程序验证下:

#include <stdio.h>
#include <sys/time.h>
#include <sys/syscall.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    struct timeval tv;
    int ret;
    if ((ret=gettimeofday(&tv, NULL))<0) {
        fprintf(stderr, "gettimeofday call failed\n");
    }else{
        fprintf(stdout, "seconds:%ld\n", (long int)tv.tv_sec);
    }

    fprintf(stdout, "pid:%d\n", (int)getpid());
    fprintf(stdout, "thread id:%d\n", (int)syscall(SYS_gettid));
    return 0;
}

编译为可执行文件后,我们可以用strace来验证:

strace -o temp ./vdso
grep getpid temp
grep gettimeofday temp

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。