Ich habe letztes Jahr Betriebssysteme verwendet, bei denen ich Benutzerkontexte (im Header ucontext.h
definiert) verwendet habe, um einen Thread-Scheduler (in dem jeder Thread einen Prozess simuliert) für ein Projekt zu implementieren. Ich nehme an einem Vortrag teil und werde über Benutzerkontexte sprechen, und mir ist gerade eingefallen, dass ich, obwohl ich dieses Projekt letztes Jahr gemacht habe, nicht wirklich verstehe, was genau der Systemaufruf getcontext
tatsächlich tut.
Die man-Seiten für getcontext
geben an, dass sie "die Struktur initialisiert, auf die ucp auf den gerade aktiven Kontext zeigt." Für das Argument setcontext
heißt es außerdem: "Wenn das Argument ucp mit getcontext () erstellt wurde, wird die Programmausführung fortgesetzt, als wäre der entsprechende Aufruf von getcontext () gerade zurückgekehrt." Okay, ich verstehe das.
Also, hier ist, worüber ich verwirrt bin. Normalerweise würde ich für die Art, wie ich es gelernt habe, einen Kontextwechsel durchführen, die ucontext_t
struct initialisieren und sie wie folgt tauschen / setzen:
Wenn ich getcontext
in kleineren Programmen weglasse, passiert nichts Interessantes. In etwas größeren Programmen, in denen mehr Kontextwechsel über Benutzerkontexte stattfindet, erhalte ich einen Segmentierungsfehler, der nur aufgelöst wird, indem getcontext
wieder hinzugefügt wird.
Was genau macht getcontext
? Warum kann ich nicht einfach ein ucontext_t
struct zuweisen, initialisieren, indem ich die Felder uc_stack
und uc_sigmask
initialisiere und makecontext
ohne getcontext
aufruft? Gibt es eine notwendige Initialisierung, die getcontext
ausführt, die makecontext
nicht ausführt?
Ich habe die GNU-libc-Implementierung für ucontext auf x86 / linux-Architekturen betrachtet, daher könnte es verschiedene Implementierungen geben, für die das Folgende nicht gilt.
Das GNU libc-Handbuch besagt Folgendes:
Der an den maccontext übergebene ucp-Parameter wird durch einen Aufruf von getcontext initialisiert.
Wenn Sie mcontext_t in glibc / sysdeps / unix / linux / x86 / sys / ucontext.h betrachten, gibt es einen Zeiger auf den Fließkommazustand (fpregset_t fpregs), der in getcontext () initialisiert und in setcontext wieder dereferenziert wird ( ). Es wird jedoch nicht mit makecontext () initialisiert. Ich habe einen schnellen Test mit GDB gemacht und ich habe einen segfault in setcontext () wenn ich versuche den Zeiger auf den Gleitkommakontext in einer ucontext_t Struktur zu dereferenzieren, die nicht von getcontext () initialisiert wurde:
= & gt; 0x00007ffff784308c & lt; + 44 & gt ;: fldenv (% rcx)
Tags und Links c posix operating-system ucontext