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:
(0x7ffff7ffad94 + 0xffffffffffffd30d)
(0x7ffff7ff80a8
) and put it in rax (to be returned)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.
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 (subject to ASLR). 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) and pmap(1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With