Was kann die Ursache für eine spontane EPIPE Fehler ohne Ende Aufruf von close() oder Absturz?
Ich habe eine Anwendung, die besteht aus zwei Prozessen (nennen wir Sie A und B), die miteinander verbunden sind durch die Unix-domain-sockets. Die meisten der Zeit, es funktioniert gut, aber einige Nutzer berichten das folgende Verhalten:
- A sendet eine Anfrage an B. Dies funktioniert. Einer beginnt nun das Lesen der Antwort von B.
- B sendet eine Antwort auf A. Die entsprechende write () - Aufruf gibt einen Fehler EPIPE, und als ein Ergebnis B close() der socket. Jedoch hat nicht close() der socket, noch war es ein Absturz.
- Eine read () - Aufruf gibt 0 zurück, der angibt, das Ende der Datei. A denkt, dass B vorzeitig die Verbindung geschlossen.
Benutzer haben auch berichtet, Abweichungen von diesem Verhalten, z.B.:
- A sendet eine Anfrage an B. Dies funktioniert teilweise, aber vor der gesamten Anfrage gesendet wird, ist Ein write () - Aufruf zurückgegeben wird EPIPE, und als Ergebnis wird eine close () - socket. Aber B nicht close() der socket, noch war es ein Absturz.
- B liest eine partielle Anfrage und dann wird plötzlich ein EOF.
Das problem ist, ich kann nicht reproduzieren dieses Verhaltens lokal auf allen. Ich habe versucht, OS X und Linux. Die Benutzer sind auf eine Vielzahl von Systemen, meist Linux und OS X.
Dinge habe ich bereits versucht und geprüft:
- Doppel-close () - bugs (close() aufgerufen wird zweimal auf die gleiche Datei-Deskriptor): wahrscheinlich nicht, denn das würde das Ergebnis in EBADF Fehler, aber ich habe Sie nicht mehr gesehen.
- Erhöhung der maximalen Datei-Deskriptor-Grenze. Ein Benutzer berichtet, dass dies für ihn gearbeitet, der rest berichtete, dass es nicht.
Was kann sonst möglicherweise zu Verhalten wie diese? Ich weiß, für bestimmte, dass weder A noch B close() der socket-vorzeitig, und ich weiß sicher, dass keiner von Ihnen abgestürzt, weil sowohl A als auch B in der Lage waren, um den Fehler zu melden. Es ist, als ob der kernel plötzlich beschlossen, ziehen Sie den Netzstecker aus der Steckdose für einige Grund.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vielleicht könnten Sie versuchen, strace, wie beschrieben in: http://modperlbook.org/html/6-9-1-Detecting-Aborted-Connections.html
Ich gehe davon aus, dass Ihr problem wie hier beschrieben: http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
Leider bin ich ein ähnliches problem mich, schafft es aber nicht, um es fest mit der gegebenen Ratschläge. Jedoch, vielleicht, SO_LINGER, was für Sie arbeitet.
shutdown()
kann haben aufgerufen wurde eine der
socket-Endpunkte.
Wenn die beiden Seiten können Gabel und ausführen
Kind-Prozess, sicherzustellen, dass die
FD_CLOEXEC
(close-on-exec) - flag gesetzt ist, auf die
socket-file-Deskriptor, wenn Sie nicht
beabsichtigen, es zu sein, geerbt von der
Kind. Ansonsten wird der Kind-Prozess
könnte (versehentlich oder anderweitig) werden
die Bearbeitung Ihrer socket-Verbindung.
Ich würde auch schauen, dass es keine hinterhältigen firewall in der Mitte. Ist es möglich, eine intermediate-forwarding-Knoten auf der route sendet eine
RST
. Der beste Weg, um track down ist natürlich der packet sniffer (oder seine GUI cousin.)