【问题标题】:time(2) in static executable is calling regular syscall - that is slower than vdso call. why?静态可执行文件中的 time(2) 正在调用常规系统调用 - 这比 vdso 调用慢。为什么?
【发布时间】:2018-07-31 02:21:20
【问题描述】:

我有一个简短的测试程序:

  • 当我将它编译为静态可执行文件 (gcc -static) 时,strace 显示 time(2) 和 getimeofday(2) 正在执行系统调用
  • 当我动态编译它时,我在 strace 输出中看不到系统调用!

我们如何解释这种差异?

(gcc - 4.8.4 操作系统:3.13.0-153-generic #203-Ubuntu SMP libc:2.19)

静态可执行文件

# 编译静态链接的exe gcc -静态 -g tm.c # 运行 strace strace ./a.out # strace 输出 写(1,“时间(2)\ n”,8时间(2) ) = 8 时间([1533002994])= 1533002994 写(1,“5b5fc4f2\n”,95b5fc4f2 ) = 9 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({1, 0}, 0x7ffc2fca7510) = 0 时间([1533002995])= 1533002995 写(1,“5b5fc4f3\n”,95b5fc4f3 ) = 9

动态可执行文件

# 编译elf exe(动态) gcc -g tm.c # 运行 strace strace ./a.out # strace 输出 写(1,“时间(2)\ n”,8时间(2) ) = 8 写(1,“5b5fc533\n”,95b5fc533 ) = 9 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({1, 0}, 0x7ffc1186d430) = 0 写(1,“5b5fc534\n”,95b5fc534 ) = 9

测试程序

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


main()
{
        time_t tt;
        struct timeval tv;

        printf("time(2)\n");
        time(&tt);
        printf("%x\n",tt);
        sleep(1);
        time(&tt);
        printf("%x\n",tt);
        sleep(1);
        time(&tt);
        printf("%x\n",tt);

        printf("gettimeofday\n");

        gettimeofday(&tv,NULL);
        printf("%x\n",tv.tv_sec);
        sleep(1);
        gettimeofday(&tv,NULL);
        printf("%x\n",tv.tv_sec);
        sleep(1);

        gettimeofday(&tv,NULL);
        printf("%x\n",tv.tv_sec);
        sleep(1);


        return 0;
}

【问题讨论】:

  • 不确定最佳 dup 目标,但有很多类似的问题。
  • 这仍然无法解释为什么它显示在静态可执行文件的 strace 中 - 它是在静态可执行文件中执行 vsyscall 吗?
  • 静态可执行文件没有 ld.so 来解释 VDSO,所以 libc 不同。
  • 因此静态可执行文件必须执行常规系统调用 - 这比 vsyscall/vdso 调用慢;所以有区别(所以它不是重复的)——MichaelMoser 23 分钟前

标签: linux glibc


【解决方案1】:

内核提供的 vDSO 与 ELF 文件具有相同的布局,因此为了在其中找到系统调用的用户空间实现,该进程需要 ELF 解析器和动态链接器的其他部分,用于符号查找和基本搬迁处理。另一方面,静态链接的可执行文件中应该缺少动态链接器(尽管在 glibc 情况下调用某些函数,例如 fopen 会导致动态链接器的静态链接)。

【讨论】:

    猜你喜欢
    • 2014-09-28
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多