0

I have a short test program:

  • when I compile it as a static executable (gcc -static) then strace shows that time(2) and getimeofday(2) are doing a system call
  • when I compile it dynamically then I don't see the system call in strace output!

How can we explain this discrepancy?

(gcc - 4.8.4 OS: 3.13.0-153-generic #203-Ubuntu SMP libc: 2.19)

Static executable

# compiling statically linked exe
gcc -static -g tm.c

# running strace 
strace ./a.out


# strace output
write(1, "time(2)\n", 8time(2)
)                = 8
time([1533002994])                      = 1533002994
write(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
time([1533002995])                      = 1533002995
write(1, "5b5fc4f3\n", 95b5fc4f3
)               = 9

Dynamic executable


# compiling elf exe (dynamic)
gcc -g tm.c

# running strace
strace ./a.out

# strace output
write(1, "time(2)\n", 8time(2)
)                = 8
write(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
write(1, "5b5fc534\n", 95b5fc534
)               = 9

Test program

#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;
}
Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
MichaelMoser
  • 3,172
  • 1
  • 26
  • 26
  • Possible duplicate of [What are vdso and vsyscall?](https://stackoverflow.com/questions/19938324/what-are-vdso-and-vsyscall) – o11c Jul 31 '18 at 02:30
  • Not sure of the best dup target, but there are a *lot* of similar questions. – o11c Jul 31 '18 at 02:31
  • That still does not explain why it is is showing in the strace for the static executable - is it doing a vsyscall in the static executable? – MichaelMoser Jul 31 '18 at 02:36
  • Static executables don't have an ld.so to interpret the VDSO, so the libc is different. – o11c Jul 31 '18 at 02:41
  • so static executable has to do a regular syscall - that is slower than vsyscall/vdso call; so there is a difference (so it's not a duplicate) – MichaelMoser 23 mins ago – MichaelMoser Jul 31 '18 at 03:24

1 Answers1

0

The vDSO provided by the kernel has the same layout as an ELF file, so in order to find the userspace implementations of system calls there, the process needs an ELF parser and other parts of the dynamic linker, for symbol lookup and basic relocation processing. On the other hand, the dynamic linker is supposed to be missing in statically linked executables (although calling certain functions such as fopen causes static linking of the dynamic linker in the glibc case).

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92