[httpd] <defunct> Problem beheben

gammla

Member
Hallo!
Ich habe immer wieder [httpd] <defunct> Prozesse.
Nach meiner Recherche werden diese Prozesse durch unsaubere Programmierung hervorgerufen.

Da ich das CMS Joomla verwende ist es bei so vielen Codezeilen ja nicht auszuschließen, dass da mal was "unsauber" geworden ist.

Doch wie kann ich herausfinden, wo der Fehler tatsächlich liegt?
Kann ich den Verursacher irgendwie in einem Log ausfindig machen und folglich beheben?

EDIT: Mir ist gerade aufgefallen, dass das besser unter die Kategorie "Webserver" gepasst hätte. Bitte bei Bedarf verschieben!

Gruß,
gammla
 
Last edited by a moderator:
Da ich das CMS Joomla verwende ist es bei so vielen Codezeilen ja nicht auszuschließen, dass da mal was "unsauber" geworden ist.
Das Problem ist nicht, dass Joomla unsauber programmiert ist (nagut, das auch...), sondern dass das Skript (sofern tatsächlich Joomla der Verursacher ist) ein Apache-Modul, vermutlich mod_php, zum Absturz bringen kann.

Doch wie kann ich herausfinden, wo der Fehler tatsächlich liegt?
Kann ich den Verursacher irgendwie in einem Log ausfindig machen und folglich beheben?
Erhöhe das LogLevel des Apache httpd und verfolge ggf. einen (oder mehrere) der Webserver-Prozesse mit strace.
 
Ich habe mal das LogLevel heruntergestellt.
Dabei fällt auf, dass relativ zeitgleich im Error-Log folgende Meldungen ausgegeben wird:

Code:
 [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 8 children, there are 0 idle, and 11 total children

[info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 16 children, there are 0 idle, and 23 total children

Ob das jetzt schon die Ursache ist weiß ich nicht. Hier meine apache prefork Einstellungen (Dem Server stehen 4GB RAM zur Verfügung):
Code:
<IfModule prefork.c>
StartServers      2
MinSpareServers    2
MaxSpareServers   4
ServerLimit      100
MaxClients       100
MaxRequestsPerChild  300
</IfModule>

Code:
Timeout 20
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 2

Eigentlich liefern ja Fehlermeldungen schon die Lösung:
you may need to increase StartServers, or Min/MaxSpareServers

Allerdings glaube ich nicht, dass noch mehr "Server" gestartet werden müssen/sollen. Nach server-status besteht zumindest kein Mangel an freien httpd Prozessen.

EDIT: Nachtrag:

Ich bin mir mittlerweile recht sicher, dass der httpd defunct mit folgender Fehlermeldung zusammenhängt:

(32)Broken pipe: core_output_filter: writing data to the network
 
Last edited by a moderator:
So wie es aussieht hängen die oben genannten Dinge nicht mit dem httpd defunct zusammen! Die broken pipe kann wohl vorkommen, wenn einer die Seite beim Laden abbricht und "[info] server seems busy" konnte tatsächlich durch die Erhöhung der "Min/MaxSpareServers" gelöst werden!

Ich habe mal ein strace ausgeführt während ein solcher httpd defunct "erzeugt" wurde:

Code:
strace -f -o apachecalls.log -tt -p 8659

Code:
8659  12:18:14.216997 select(0, NULL, NULL, NULL, {0, 210000}) = 0 (Timeout)
8659  12:18:14.426797 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:14.426923 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:15.426825 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:15.426950 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:16.426817 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:16.426929 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:17.426851 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:17.426972 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:18.426850 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:18.426961 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:19.426859 write(6, "!", 1)  = 1
8659  12:18:19.427026 socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 11
8659  12:18:19.427146 fcntl(11, F_GETFL) = 0x2 (flags O_RDWR)
8659  12:18:19.427248 fcntl(11, F_SETFL, O_RDWR|O_NONBLOCK) = 0
8659  12:18:19.427347 connect(11, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
8659  12:18:19.427567 poll([{fd=11, events=POLLOUT}], 1, 3000) = 1 ([{fd=11, revents=POLLOUT}])
8659  12:18:19.427700 getsockopt(11, SOL_SOCKET, SO_ERROR, [-1125479927760551936], [4]) = 0
8659  12:18:19.427815 write(11, "OPTIONS * HTTP/1.0\r\nUser-Agent: "..., 85) = 85
8659  12:18:19.428375 close(11)         = 0
8659  12:18:19.428882 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:19.428999 select(0, NULL, NULL, NULL, {1, 0}) = ? ERESTARTNOHAND (To be restarted)
8659  12:18:19.437315 --- SIGCHLD (Child exited) @ 0 (0) ---
8659  12:18:19.437392 select(0, NULL, NULL, NULL, {0, 992000}) = 0 (Timeout)
8659  12:18:20.428861 write(6, "!", 1)  = 1
8659  12:18:20.428971 socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 11
8659  12:18:20.429086 fcntl(11, F_GETFL) = 0x2 (flags O_RDWR)
8659  12:18:20.429174 fcntl(11, F_SETFL, O_RDWR|O_NONBLOCK) = 0
8659  12:18:20.429263 connect(11, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
8659  12:18:20.429460 poll([{fd=11, events=POLLOUT}], 1, 3000) = 1 ([{fd=11, revents=POLLOUT}])
8659  12:18:20.429581 getsockopt(11, SOL_SOCKET, SO_ERROR, [-1125479927760551936], [4]) = 0
8659  12:18:20.429692 write(11, "OPTIONS * HTTP/1.0\r\nUser-Agent: "..., 85) = 85
8659  12:18:20.429854 close(11)         = 0
8659  12:18:20.429966 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 9424
8659  12:18:20.430118 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:20.430209 select(0, NULL, NULL, NULL, {1, 0}) = ? ERESTARTNOHAND (To be restarted)
8659  12:18:20.436300 --- SIGCHLD (Child exited) @ 0 (0) ---
8659  12:18:20.436363 select(0, NULL, NULL, NULL, {0, 994000}) = 0 (Timeout)
8659  12:18:21.429900 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 9419
8659  12:18:21.430072 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:21.430172 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:22.429941 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:22.430077 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:23.429938 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:23.430066 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:24.429982 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:24.430109 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:25.429944 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:25.430051 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:26.429949 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:26.430048 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:27.430009 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:27.430166 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:28.429978 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:28.430076 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:29.430212 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:29.430353 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:30.431043 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:30.431156 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:31.431028 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:31.431126 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:32.431044 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:32.431142 select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
8659  12:18:33.431086 wait4(-1, 0x7fff914e902c, WNOHANG|WSTOPPED, NULL) = 0
8659  12:18:33.431197 select(0, NULL, NULL, NULL, {1, 0} <unfinished ...>

Folgene Zeilen kommen mir komisch vor:
Code:
 12:18:19.427700 getsockopt(11, SOL_SOCKET, SO_ERROR, [-1125479927760551936], [4]) = 0
8659  12:18:20.436300 --- SIGCHLD (Child exited) @ 0 (0) ---
8659  12:18:20.436363 select(0, NULL, NULL, NULL, {0, 994000}) = 0 (Timeout)

Leider kann ich mit den Angaben recht wenig anfangen!

Könnt ihr mir helfen?

Gruß,

gammla
 
Arg viel kann man mit dem Fragment nicht anfangen (mit dem Ausschnitt schon gar nicht).
Das Programm war gerade dabei, die Optionen eines Sockets abzufragen, um anschließend darüber eine Antwort an den anfragenden Client zu schreiben und danach die Verbindung zu schließen. Danach wurde abgefragt, ob ein anderer Kindprozess zwischenzeitlich beendet worden ist (was bei der ersten Abfrage der Fall war und bei der zweiten nicht), um Zombies zu vermeiden. Was in der Zwischenzeit geschieht, kann man mit strace nicht ermitteln, da damit nur Systemaufrufe protokolliert werden können. Auf jeden Fall wird der Prozess durch das Signal SIGCHLD unterbrochen, da ein anderer Kindprozess beendet wurde, woraufhin noch 994ms gewartet wurde um anschließend den Status des beendeten Prozesses abzufragen, wodurch wiederum ein Zombie-Prozess verhindert wurde. Alles ganz normal.
 
Nachtrag: Die Schlussfolgerung, die man aus dem strace-Output ziehen kann ist, dass die Zombies nicht am Apache liegen, da der sehr bemüht ist, diese zu vermeiden (ständige reguläre Abfragen und Abfragen im Signalhandler).

Das bedeutet, dass der Fehler im Code liegt, der dynamisch nachgeladen wird, also in einem Modul, wie z.B. der PHP-Interpreter. Da das Sharedobjectfile im Kontext des httpd läuft, wird es nicht mit seinem eigenen Namen angezeigt. Innerhalb des Moduls wird ein Kindprozess erzeugt, der (auf Grund eines Fehlers) unerwartet beendet wird und dessen Exitstatus daher nicht abgefragt wird.
 
Back
Top