How can confirm whether __GI___clock_gettime() belongs to fast system call or not?

0

How can confirm whether __GI___clock_gettime() is implemented as a fast system call or not on the X86_64 platform?

Here is the related backtrace:

(gdb) bt
#0  0x00007ffc41da89fa in ?? ()
#1  0x00007fa90785aaf0 in ?? ()
#2  0x00007fa905a16876 in __GI___clock_gettime (clock_id=0, tp=0x7fa90785aac0) at ../sysdeps/unix/clock_gettime.c:115

Following the advice of Employed Russian, I redo the test with GDB on X86_64. But I found clock_gettime() function do system call(maybe I am wrong). Here is the test code snippet:

   #include<time.h>

   int main()
   {
       clock_gettime(CLOCK_REALTIME, NULL);
   }

Here is the related assembly code:

(gdb) disassemble
Dump of assembler code for function clock_gettime:
=> 0x00000000004428b0 <+0>:     movslq %edi,%rdi
   0x00000000004428b3 <+3>:     mov    $0xe4,%eax
   0x00000000004428b8 <+8>:     syscall
   0x00000000004428ba <+10>:    cmp    $0xfffffffffffff000,%rax
   0x00000000004428c0 <+16>:    ja     0x4428c8 <clock_gettime+24>
   0x00000000004428c2 <+18>:    repz retq
   0x00000000004428c4 <+20>:    nopl   0x0(%rax)
   0x00000000004428c8 <+24>:    mov    $0xffffffffffffffd0,%rdx
   0x00000000004428cf <+31>:    neg    %eax
   0x00000000004428d1 <+33>:    mov    %eax,%fs:(%rdx)
   0x00000000004428d4 <+36>:    mov    $0xffffffff,%eax
   0x00000000004428d9 <+41>:    retq
End of assembler dump.
c
glibc
libc
asked on Stack Overflow Jul 19, 2020 by John • edited Aug 8, 2020 by John

2 Answers

1

How can confirm whether __GI___clock_gettime() is implemented as a fast system call or not

You can disassemble it with disas GDB command. You will see that it calls __vdso_clock_gettime.

You can also compile and link statically (to avoid dynamic linking) a trivial test program calling clock_gettime, and observe with strace which system calls it performs. Here is what I see for a program built with gcc -static -no-pie t.c:

execve("./a.out", ["./a.out"], 0x7ffc17582cd0 /* 46 vars */) = 0
brk(NULL)                               = 0x55555566e000
brk(0x55555566f1c0)                     = 0x55555566f1c0
arch_prctl(ARCH_SET_FS, 0x55555566e880) = 0
uname({sysname="Linux", nodename="redacted", ...}) = 0
readlink("/proc/self/exe", "/tmp/a.out", 4096) = 10
brk(0x5555556901c0)                     = 0x5555556901c0
brk(0x555555691000)                     = 0x555555691000
exit_group(0)                           = ?
+++ exited with 0 +++

Note lack of any kind of time-related system calls.

answered on Stack Overflow Jul 19, 2020 by Employed Russian
1

To get a quick estimate: Take a look at man clock_gettime. If it's in the third manual book, it is definitely a library function, if it is in the second book it could be a system call. Here we got the page CLOCK_GETRES(2), a good sign.

To be sure, a look at the respective system call table is necessary. Here you can see that clock_gettime has the system call number

  • 265 on x86
  • 228 on x86-64
  • 263 on arm
  • 113 on arm64

In all cases it is a direct system call and not a library function. This is not always the case, for example open is a direct system call on x86, but not on x86-64 and arm64 cause the syscall was replaced with open_at.

answered on Stack Overflow Jul 19, 2020 by fcdt

User contributions licensed under CC BY-SA 3.0