Warum verwendet strace keine Testsyscalls, um ihre Indizes in der Systemaufruftabelle herauszufinden?

382
user322908

Ich verstehe, dass der straceBefehl verwendet wird ptrace(PTRACE_PEEKUSER, child, __builtin_offsetof(struct user, regs.orig_eax)), um den Index eines Systemaufrufs zu ermitteln, bei dem das Tracee-Kind eingeschlossen ist. Um dann den Index in den syscall-Funktionsnamen zu übersetzen, wurden Tabellen erstellt, die aus den in der Installation vorhandenen Linux-Quellcode-Headern erstellt wurden.

Diese Methode muss undokumentiert und fehleranfällig sein, da der Speicherort und die Syntax der Quelltextdeklarationen nicht dokumentiert sind, von grepping gefunden werden müssen und sich auf unbekannte Weise ändern können. Kann ich das richtig sagen?

Wenn dem so ist, warum, warum, würde straceich die folgende Methode nicht verwenden, scheint mir einfacher, stützt sich nur auf Dokumentation und ist daher idiotensicher.

Beim Start des ersten Laufs nach dem Neustart stracewird ein Testsyscall gesendet, einer für jede Syscall-Funktion, der diese abfängt und beobachtet, welchen Syscall-Index das Kind verwendet. Dies ergibt eine vollständige und korrekte benutzerdefinierte Tabelle, die in einer Datei gespeichert werden kann, die weiteren Aufrufen von bekannt ist strace.

Ich bin sicher, dass diese Methode in Betracht gezogen werden muss, da sie nichts besonders Geniales ist. Es muss also etwas falsch sein. Was ist falsch??

1
Wie würde es diese Testsystemaufrufe machen, außer durch die Verwendung der Konstanten aus den System- / Kernel-Headern? R.. vor 8 Jahren 0
Auch "first run after reboot" ist ein Konzept, das überhaupt keinen Sinn macht. Wie würde es so etwas überhaupt erfahren? R.. vor 8 Jahren 0
@R .. ?? `open (foobar.txt, O_RDONLY)` Kein undokumentiertes Material ist erforderlich user322908 vor 8 Jahren 0
@R .. was "the first run" angeht, wollte ich einfach nicht die Situation riskieren, dass jemand einige Header ändert, den Kernel neu kompiliert und mit dem neuen Kernel neu startet (der übrigens die aktuelle `strace 'brechen kann "Ich glaube). Ich muss also sicherstellen, dass ich, wenn ich die Tabelle speichere, nicht jedes Mal, wenn "strace" aufgerufen wird, sie berechnen möchte, sie beim Neustart gelöscht wird. Sicherlich muss es in Linux eine Möglichkeit geben, zu sagen, ob ich nach dem Neustart zum ersten Mal aufgerufen werde. Sicherlich muss es eine Datei geben, die beim Neustart berührt / erstellt wird, damit ich meinen Zeitstempel damit vergleichen kann? user322908 vor 8 Jahren 0
@R .. Zum Beispiel sagt der Systemaufruf `sysinfo`, wie lange ich gebootet habe, und vergleicht das mit dem Zeitstempel der Datei, in der ich die Tabelle gespeichert habe. Ich weiß, ob ich die Datei löschen und erneut starten möchte. user322908 vor 8 Jahren 0
Woher wissen Sie, dass "open (foobar.txt, O_RDONLY)" genau einen Syscall ergibt und das ist "SYS_open"? Es könnte `SYS_openat` verwendet werden. Dies kann dazu führen, dass andere Systemaufrufe als Teil der verzögerten Bindung im dynamischen Linker stattfinden, wenn dies der erste Aufruf von "open" ist. Oder es können intern andere Systemaufrufe für einen anderen Zweck erfolgen. Es gibt keine triviale Eins-zu-Eins-Zuordnung, die Sie zwischen Bibliotheksaufrufen und Systemaufrufen annehmen können. R.. vor 8 Jahren 1
Wenn Sie der Meinung sind, dass sich die Definitionen der Systemrufnummern nach dem Neustart ändern könnten, haben Sie einige ernsthafte Missverständnisse, die möglicherweise erklären, warum Sie diese Frage zuerst stellen. Sie sind ein fester Bestandteil der öffentlichen Kernel-API / ABI. Damit dies nicht der Fall ist, konnten für einen Kernel gebaute Binärdateien nicht für einen anderen Kernel verwendet werden. R.. vor 8 Jahren 0
@R ... OK Ich verstehe, dass es keine Eins-Eins-Entsprechung zwischen lib-Aufrufen und sys-Aufrufen gibt. Ausgezeichnet. Ich verstehe den zweiten Teil nicht, in dem Sie "absoluten Teil der öffentlichen Kernel-API" sagen. Wenn dies der Fall ist, können Sie mich darauf hinweisen, wo diese API dokumentiert ist und auf der Plattform "Open-Plattform-Aufruf ist Index 2" oder so ähnlich steht. user322908 vor 8 Jahren 0
@ R .. natürlich habe ich Missverständnisse. Wenn ich vollkommenes Verständnis hätte, würde ich diese Frage nicht stellen, sondern beantworten. Ihr Kommentar ist unangemessen. user322908 vor 8 Jahren 0
@R .. Diese Dokumentationsseite man7.org/linux/man-pages/man2/syscalls.2.html besagt eindeutig, dass ich bestimmte Bibliotheksfunktionen aufrufen kann, was zu einem entsprechenden Syscall (am Ende) führt. user322908 vor 8 Jahren 0
Manpages sind nicht normativ. Sie sollen beschreibend sein, aber manchmal sind die Beschreibungen nicht ganz korrekt. Wenn Sie der Meinung sind, dass dieser Text irreführend ist, senden Sie bitte einen Fehlerbericht an das Linux-Manpages-Projekt. R.. vor 8 Jahren 0
Bei den festgelegten Systemrufnummern handelt es sich lediglich um die Linux-Stabilitätsrichtlinie. Auf Systemen ohne eine solche Richtlinie haben Sie keine Abwärtskompatibilität und alle Binärdateien, die Syscall-Nummern verwenden (dh statische Binärdateien und dynamische Binärdateien, die die Funktion `syscall ()` verwenden) sind an den jeweiligen Kernel gebunden Version, für die sie gebaut wurden. Sie finden die Linux-Stabilitätsrichtlinie irgendwo in der Kernel-Dokumentation, aber es sollte nicht einmal angegeben werden. Dies ist nur der grundlegendste gesunde Menschenverstand über Kompatibilität. R.. vor 8 Jahren 0
@R .. Nicht nur das, sondern historisch gesehen, betreffen Änderungen an der Syscall-Tabelle nur das Hinzufügen und Entfernen neuer Syscalls. Es gibt viele Lücken in der Tabelle, in denen veraltete und schließlich entfernte Syscalls einfach nicht mehr existieren (und `-ENOSYS 'auslösen). Die Tabelle wurde nie "verschoben", sodass sich die Bedeutung eines Syscalls ändert. Wenn ein Syscall geändert werden muss, wird eine neue Version mit einem ähnlichen Namen hinzugefügt. forest vor 5 Jahren 0

1 Antwort auf die Frage

1
forest

Denn es gibt kein Konzept für einen Syscall-Namen auf diesem niedrigen Niveau. Es gibt keine Möglichkeit strace, "Hey, lass uns fcntl()anrufen und sehen, was die Nummer ist!". Es kann nur Anrufe tätigen, die auf den Syscall-Nummern selbst basieren. Dies liegt daran, dass ein Syscall ausgeführt wird, wenn die Syscall-Nummer im eaxoder raxRegister gespeichert wird und der Prozess int 0x80oder aufruft syscall.