Why doesn't time() from time.h have a syscall to sys_time?

不羁的心 提交于 2019-12-10 12:45:07

问题


I wrote a very simple program with calls time() to illustrate the use ofstrace, but I'm having a problem; the time() call doesn't seem to actually produce a syscall!

I ended up stepping into the time() function in GDB and now I'm more confused than ever. From the disassembly of the time() function:

0x7ffff7ffad90 <time>:  push   rbp
0x7ffff7ffad91 <time+1>:    test   rdi,rdi
0x7ffff7ffad94 <time+4>:    mov    rax,QWORD PTR [rip+0xffffffffffffd30d]        # 0x7ffff7ff80a8
0x7ffff7ffad9b <time+11>:   mov    rbp,rsp
0x7ffff7ffad9e <time+14>:   je     0x7ffff7ffada3 <time+19>
0x7ffff7ffada0 <time+16>:   mov    QWORD PTR [rdi],rax
0x7ffff7ffada3 <time+19>:   pop    rbp
0x7ffff7ffada4 <time+20>:   ret 

How is this function actually getting the current time if it does not call the kernel? Its flow is:

  • Prologue
  • Get some value from (0x7ffff7ffad94 + 0xffffffffffffd30d) (0x7ffff7ff80a8) and put it in rax (to be returned)
  • Check if rdi (first argument) was null
  • If not put the value in rax (return value) there also
  • Epilogue

This makes sense with the functionality of time(); if the argument is null, it just returns the value, but if not it also puts it in the argument. The question I have is, where is it getting the time value? What's so magical about address 0x7ffff7ff80a8, and how does it do this without a syscall?

I'm using GCC 6.3.0 and Ubuntu GLIBC 2.24-9ubuntu2.2.


回答1:


Read time(7). Probably your call to time(2) uses the vdso(7) (maybe via clock_gettime(2) or via __vdso_time). If vdso(7) is used,

When tracing systems calls with strace(1), symbols (system calls) that are exported by the vDSO will not appear in the trace output.

Details could be kernel and libc specific (and of course architecture specific).

For similar vDSO reasons, strace date don't show any time-related syscalls.

And vDSO is a really handy feature. Thanks to it, timing calls (e.g. clock_gettime(2)...) go really quick (about 40 nanoseconds on my i5-4690S). AFAIU, no context switch (or user to kernel mode transition) is happening.

So your 0x7ffff7ff80a8 is probably sitting in the vDSO (and the kernel ensures it contains the current time). You might check by using proc(5) (e.g. reading and showing /proc/self/maps from your program), or perhaps using ldd(1).



来源:https://stackoverflow.com/questions/48252494/why-doesnt-time-from-time-h-have-a-syscall-to-sys-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!