Ich schreibe ein systemkritisches Programm für eine Linux-Distribution, die ich entwickle. Es muss sich beim Empfang bestimmter Signale neu starten, um einen Absturz zu vermeiden. Das Problem ist, dass ich das Signal nach dem Neustart nicht wieder aktivieren kann. Das heißt, das Signal kann nicht zweimal empfangen werden. Wenn der neue Prozess signal() aufruft, um das Signal einzurichten, wird SIG_DFL zurückgegeben. Jedes Mal. Auch wenn ich es zweimal hintereinander rufe - was bedeutet, dass es nie an erster Stelle gesetzt wurde. Wird eine seltsame Flagge vom ursprünglichen Prozess übernommen?Signale werden über execv nicht korrekt wieder aktiviert()
Antwort
Sie fallen mit der Tatsache, dass Sie im Wesentlichen versuchen, ein Signal rekursiv umzugehen.
Wenn ein Signalhandler mit signal()
registriert wird, wird diese Signalnummer blockiert, bis der Signalhandler zurückkehrt - tatsächlich blockiert der Kernel/libc diese Signalnummer, wenn der Signalhandler aufgerufen wird, und entsperrt ihn nach Rückkehr des Signalhandlers. Da du nie wieder vom Signalhandler zurückkehrst (statt eine neue Binärdatei), bleibt SIGUSR1
blockiert und wird somit beim 2. Mal nicht abgefangen.
Dies kann durch die Prüfung /proc/</pid>/status
vor und nach dem Senden der ersten SIGUSR1
gesehen werden.
Bevor:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000000
SigCgt: 0000000000000200
After:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000200
SigCgt: 0000000000000200
anzumerken, dass SigCgt
Signal zeigt an 10 registriert ist (die Anzahl ist ein Bitfeld; 10. Bit gesetzt ist, die zu SIGUSR1 entspricht, siehe man signal(7)
für die Zahlen). SigBlk
ist leer, bevor SIGUSR
an Ihren Prozess gesendet wird, aber nach dem Senden des Signals enthält es SIGUSR1
.
Sie haben zwei Möglichkeiten, dies zu lösen:
a). entsperren SIGUSR
manuell vor execl
in sighandler
Aufruf:
sigset_t sigs;
sigprocmask(0, 0, &sigs);
sigdelset(&sigs, SIGUSR1);
sigprocmask(SIG_SETMASK, &sigs);
b). Verwenden Sie sigaction
mit dem SA_NODEFER
Flag anstelle von signal
, um den Signalhandler zu registrieren. Dadurch wird verhindert, dass SIGUSR1
innerhalb des Signalhandlers blockiert wird:
struct sigaction act;
act.sa_handler = signalhandler;
act.sa_mask = 0;
act.sa_flags = SA_NODEFER;
sigaction(SIGUSR1, &act, 0);
Signal-Handler werden nicht über exec
weil exec
überschreibt die gesamte Adressraum, und alle Signal-Handler geerbt, die nicht würde zurückgesetzt dann an der falschen Stelle zeigen. Die einzige Zeit, zu der es nicht zurückgesetzt wird, ist, wenn es beispielsweise auf SIG_IGN
gesetzt ist, was nicht von dem Adressraum des Prozesses vor dem exec
abhängt.
Das ist, was ich denke. Was ich sagte, ist, dass der neue Prozess nach der Exekution * nicht * das Signal wieder setzen kann - nicht, dass er nicht übertragen wird. Egal, was ich mache, nachdem ich einen Prozess von einem Signal-Handler ausgeführt habe, kann ich das gleiche Signal nicht noch einmal einstellen. – c4757p
Haben Sie einen Code zur Hand, mit dem ich testen kann? Ich bin jetzt wirklich neugierig darauf. –
Sicher. Versuchen Sie '-10' zu töten. Sie können es nur einmal tun - es ignoriert alle nachfolgenden Versuche. http://www.box.net/shared/tgfaef5l8i – c4757p
- 1. execv Linux printf nicht
- 2. Wie kann ASP.NET LinkButton nach der Deaktivierung wieder aktiviert werden?
- 3. Signale über das Kopfhörerkabel senden
- 4. Signale werden nicht für QTabWidget erkannt
- 5. Warum werden Signale nicht einfach Ereignisse genannt?
- 6. Wie werden ANSI-Farben in ConEmu + Git Bash korrekt aktiviert?
- 7. Execv() und Const-Ness
- 8. ReSharper Daemon kann nicht aktiviert werden
- 9. Trennen Sie Signale für Modelle und wieder in Django
- 10. .net Highcharts kann das Balkendiagramm nicht korrekt wieder in mvc
- 11. Django Signale funktioniert nicht
- 12. Wie man mod_rewrite mamp korrekt aktiviert?
- 13. Googles NavigationDrawer zeichnet nicht korrekt über Karte
- 14. Strings werden nicht korrekt in PHP verkettet
- 15. Bildansicht nicht korrekt über Listview-Adapter
- 16. jQuery-Animationen werden nicht korrekt ausgeführt.
- 17. Signale im "set" -Parameter von sigtimedwait() werden nicht geliefert
- 18. Checkbox-Status nicht aktiviert, wenn anderes Kontrollkästchen aktiviert ist pyqt
- 19. iOS-Symbolleiste über Tastaturposition nicht korrekt
- 20. FileStream scheint nicht aktiviert zu werden
- 21. JNI-Debugger kann nicht aktiviert werden
- 22. Meine Cassandra kann nicht aktiviert werden
- 23. Behat3 MinkExtension konnte nicht aktiviert werden
- 24. Seltsames Problem, bei dem die Schaltfläche nicht wieder aktiviert wird, wenn die Maus nicht geklickt wird
- 25. Wie kann die Authentifizierung in MongoDB über Docker aktiviert werden?
- 26. AngularJS-Vorlagen werden nicht korrekt geladen
- 27. wieder über log4net und Unity IOC config
- 28. Mirage (Cloudflare) bewirkt, dass GMaps nicht korrekt angezeigt werden
- 29. Elementrichtlinie kann nicht korrekt verwendet werden
- 30. EmberFire Datenrelationen werden nicht korrekt aktualisiert
Ich entdeckte, dass ich es entsperren musste - ich nahm idiotisch an, dass es nicht blockierte. Jedenfalls habe ich NODEFER versucht, und das hat nicht funktioniert, aber es im Handler entsperrt, bevor der Exec Call funktioniert. Vielen Dank. – c4757p