Warum hat time () von time.h keinen syscall zu sys_time?

8

Ich habe ein sehr einfaches Programm mit den Aufrufen time() geschrieben, um die Verwendung von strace zu verdeutlichen, aber ich habe ein Problem; Der Aufruf time() scheint keinen Syscall zu erzeugen!

Ich bin dann in die time() Funktion in GDB getreten und jetzt bin ich noch verwirrter als je zuvor. Von der Demontage der Funktion time() :

%Vor%

Wie bekommt diese Funktion tatsächlich die aktuelle Uhrzeit, wenn sie den Kernel nicht aufruft? Sein Ablauf ist:

  • Prolog
  • Erhalte einen Wert von (0x7ffff7ffad94 + 0xffffffffffffd30d) ( 0x7ffff7ff80a8 ) und lege ihn in rax (um zurückgegeben zu werden)
  • Überprüfen Sie, ob rdi (erstes Argument) null war
  • Wenn nicht der Wert in rax (Rückgabewert) steht dort auch
  • Epilog

Dies macht Sinn mit der Funktionalität von time() ; Wenn das Argument null ist, gibt es nur den Wert zurück, wenn nicht, wird es auch in das Argument geschrieben. Die Frage, die ich habe, ist, wo bekommt es den Zeitwert? Was ist so zauberhaft an der Adresse 0x7ffff7ff80a8 und wie geht das ohne einen Systemaufruf?

Ich benutze GCC 6.3.0 und Ubuntu GLIBC 2.24-9ubuntu2.2.

    
Leo Tindall 14.01.2018, 17:57
quelle

1 Antwort

6

Lesen Sie time (7) . Wahrscheinlich verwendet Ihr Anruf bei time (2) das vdso(7) (vielleicht über clock_gettime (2) oder via __vdso_time ). Wenn vdso (7) verwendet wird,

  

Bei der Verfolgung von Systemaufrufen mit strace (1) , Symbolen (Systemaufrufen)          die vom vDSO exportiert werden, wird nicht in der Ablaufverfolgungsausgabe angezeigt.

Details könnten kernel- und libc-spezifisch (und natürlich architekturspezifisch) sein.

Bei ähnlichen vDSO Gründen zeigt strace date keine zeitbezogenen Systemaufrufe.

Und vDSO ist eine wirklich praktische Funktion. Dank dieser Funktion werden Timing-Aufrufe (zB clock_gettime (2) ...) wirklich ausgeführt schnell (ungefähr 40 Nanosekunden auf meinem i5-4690S). AFAIU, kein Kontextwechsel (oder Benutzer zum Kernel Modus Übergang) passiert.

Ihr 0x7ffff7ff80a8 befindet sich wahrscheinlich im vDSO (und der Kernel stellt sicher, dass es die aktuelle Zeit enthält). Sie können dies überprüfen, indem Sie proc (5) verwenden (zB lesen und /proc/self/maps in Ihrem Programm anzeigen) oder vielleicht ldd (1) .

    
Basile Starynkevitch 14.01.2018, 18:04
quelle

Tags und Links