Ich habe eine Bibliothek entwickelt, die SIGILL-Signale verarbeitet. Da ich die libc-Abhängigkeit vermeiden möchte, benutze Linux syscalls direkt. Ich habe bemerkt, dass meine Bibliothek auf einigen Linux-Systemen hängt, und nach einer Menge Debugging habe ich festgestellt, dass die Verwendung von rt_sigaction
syscall anstelle von sigaction
das Problem löst. Ich habe jedoch keine Beschreibung des Unterschieds zwischen den beiden Systemaufrufen gefunden. Weiß jemand auf SO die zugrunde liegenden Details?
Update: Ich benutze Signal-Handler, um die CPU-Unterstützung für einige ARM-Befehlserweiterungen, z.B. XScale-Anweisung MIATT
. Hier ist die Befehlssondierungsfunktion:
Im SIGILL-Handler befördere ich das PC
-Register um 4 Bytes (Größe dieser Anweisung) und ändere eines der Register, um anzuzeigen, dass der SIGILL-Handler aufgerufen wurde. Hier ist der Signal-Handler-Code.
So mache ich das Sondieren (die Funktion gibt 0 zurück, wenn der Befehl SIGILL nicht verursacht hat, 1 wenn der SIGILL-Handler aufgerufen wurde, und 2, falls der sigaction-Syscall fehlgeschlagen ist):
%Vor%Hier ist meine Implementierung von sigaction syscall stub function:
%Vor%Ich habe diesen Code im Emulator vom Android SDK (qemu) und auf Pandaboard mit Ubuntu getestet. Im Emulator läuft der Code gut (sowohl beim Emulieren von ARM9- als auch Cortex-A8-CPUs), aber bei Pandaboard hängt er am MIATT-Befehl, wenn ich __NR_sigaction verwende: Es scheint, dass nach dem Signalhandler der Code 4 Bytes nicht überspringt, aber läuft die gleiche Anweisung.
Von man sigaction
( link ) zitiere ich:
Der ursprüngliche Linux-Systemaufruf wurde als sigaction () bezeichnet. Jedoch mit das Hinzufügen von Echtzeit-Signalen in Linux 2.2, die feste Größe, Der 32-Bit-Typ "sigset_t", der von diesem Systemaufruf unterstützt wird, war nicht mehr geeignet für den Zweck. Folglich wurde ein neuer Systemaufruf, rt_sigaction (), ausgeführt hinzugefügt, um einen vergrößerten Sigset_T-Typ zu unterstützen. Der neue Systemaufruf nimmt ein viertes Argument, size_t sigsetsize, das die Größe angibt in Bytes der Signalmengen in act.sa_mask und oldact.sa_mask.
Ich habe keine definitive Antwort, aber ich werde trotzdem versuchen, etwas beizutragen:
Blick auf die Kernel-Quelle:
%Vor%vs.
%Vor%Die Differenz ist, wie ich sehe, dass rt_sigaction die gesamte sigaction Struktur kopiert, während sigaction den Speicher inline holt und verändert (mit den get / set Benutzerfunktionen) ... Ich bin mir nicht sicher, aber vielleicht braucht es mehr Zeit, um direkt auf den Speicher des Benutzerspeichers zuzugreifen, anstatt mit einer temporären Kopie zu arbeiten.
Tags und Links c linux signals linux-kernel system-calls