Re: Suche Debughilfe: child never returns from fork?

From: Bernd Walter <ticso(at)cicely12.cicely.de>
Date: Tue, 8 Apr 2008 00:32:24 +0200

On Mon, Apr 07, 2008 at 08:03:24PM +0000, Peter Much wrote:
>
> Moin Leute,
>
> ich hab hier ein ziemlich widerliches Problem.
>
> Der Code sieht so aus:
>
> > switch (bpipe->worker_pid = fork()) {
> > case -1: /* error */
> ... etc. etc. ...
> > case 0: /* child */
> > close(readp[0]); /* Close unused child fds */
> > dup2(readp[1], 1); /* dup our read to his stdout */
> > dup2(readp[1], 2); /* and his stderr */
> ... etc. etc. und irgendwann dann execvp()
> > default: /* parent */
> > break;
> > }
> ... etc. etc. ...
>
>
> Passieren tut dabei folgendes:
> - der fork() wird ausgeführt, ich hab also zweimal dasselbe Programm
> mit unterschiedlicher PID in der Prozessliste.
> - der Parent läuft normal weiter und macht seine Arbeit wie
> vorgesehen.
> - das Child steht im Status "Running" und braucht 100% system-cpu,
> und ist dementsprechend nur mit -9 killbar.
> - wenn ich mit lsof die Filehandles anschaue, dann sehe ich dass
> der close() noch nicht ausgeführt wurde.

D.h. es ist noch das originale Programm und nicht das neue per execvp?
Wenn der tatsächlich beim close hängt, dann stellt sich mir zwangsläufig
auch die Frage was das für Filehandles sind.
Das Problem mag ja durchaus am Medium der Files liegen.

> Jetzt kommt die Widerlichkeit: das Zeug läuft 500 mal korrekt ab, und
> dann bleibt es -unvorhersagbar- irgendwann einmal hängen. Aber das auch
> immer wieder mal - d.h. alle paar Tage. Und auf einer anderen,
> installationsgleichen aber deutlich schnelleren (und weniger
> vollgepackten) Maschine ist es nur einmal passiert.

Na gut - solche Programmfehler wären nichts neues.

> Der Fehler ist plötzlich aufgetaucht nachdem die Maschinen auf
> RELEASE 6.3 upgraded wurden (zuvor: RELEASE 5.5, mit identischen
> Ports).

Auch das wäre nichts neues.

> Ich kann natürlich nicht sagen, ob der Prozess aus dem fork() nicht
> raus- oder in den close() nicht reinkommt. Mir ist auch klar, dass
> der fork() derweil milliardenmal richtig ausgeführt wird...

Du hast beim case -1 auch sauber abgefangen, dass der nicht in den
case 0 durchfällt?
Und so Klassiker, wie sigchld hast du auch sauber behandelt?

> Wie kann man sowas debuggen?

Wenn der Prozess unkillbar ist, dann hilft der Kernel-Debugger, um dort
zu sehen wo der Prozess gerade steckt.
Mitunter muss man das mehrfach machen, um ein Gefühl dafür zu bekommen,
da der ja schließlich in irgendeiner Form imme rnoch läuft.

-- 
B.Walter <bernd@bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Tue 08 Apr 2008 - 00:32:56 CEST

search this site