Beendet Windows einen Dienst, der nicht auf Signale reagiert?

478
George Sovetov

Ich habe einen Dienst, der als funktioniert Local Systemund manchmal nicht mehr anhält.

Der Serviceprozess erhält ein Beendigungssignal, führt eine Bereinigung durch, aber aufgrund des Fehlers bleiben einige Threads aktiv.

SCM berichtet an das Ereignisprotokoll mit der Ereignis-ID 7011:

Beim Warten auf eine Transaktionsantwort vom ... Dienst wurde ein Timeout (30000 Millisekunden) erreicht.

Danach werden Dienste im Fenster Dienste in der Verwaltungskonsole und in der WMI als angehalten angezeigt.

Aber wie geht Windows mit dem Dienst um, wenn er nicht beendet wird? Ich kann den Dienst nicht neu starten: Der Prozess des alten Dienstlaufs sperrt immer noch Dateien und ist an Ports gebunden.

Ich gehe davon aus, dass Windows den nicht reagierenden Prozess beendet, ich kann jedoch keine Dokumentation oder Einstellungen dazu finden.

30000 ms scheinen aus HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ServicesPipeTimeout( https://support.microsoft.com/de-de/help/839803/the-windows-trace-session-manager-service-does-not-start-and-event-id ) entnommen zu werden. . Aber nach 30 Sekunden bekomme ich nur noch ein Ereignis, der Prozess ist immer noch da.

Laut Crash-Dump wurde der Haupt-Thread beendet, und in einigen warten einige Threads auf Socket WaitForSingleObject.

Wir haben den Fehler bereits beim Anbieter gemeldet und versuchen diesen zu beheben. Es ist jedoch meistens die Frage, was zu tun ist, um diesen Prozess zu beenden, ob es möglich ist, ihn ohne Neustart zu säubern.

2
Ihre Frage widerspricht dem zugrunde liegenden Problem, warum Sie es nicht neu starten können. Es gibt eine gesperrte Bedingung, dass der Service Controller normalerweise darauf wartet, dass der Prozess + die Threads ordnungsgemäß heruntergefahren werden, dies jedoch nicht ist. Daher gibt es eine Deadlock-Bedingung. In diesem Fall wartet der Dienst auf seine vordefinierte Dauer, bevor er aufgibt. Wenn Sie den Dienst neu starten möchten, müssen Sie die Prozesse manuell beenden. Wenn Sie dies langfristig beheben wollen, müssen Sie sich an den Softwarehersteller wenden. Wenn Sie eine tiefer gehende Analyse wünschen, laden Sie procmon und procexp auf, um die Diagnose genauer zu diagnostizieren oder ein Dump und Debugging durchzuführen thepip3r vor 6 Jahren 1
@ thepip3r Vielen Dank für den Vorschlag. Der Fehler wurde bereits gemeldet. George Sovetov vor 6 Jahren 0

1 Antwort auf die Frage

2
harrymc

Ihr Dienst wurde wahrscheinlich gestoppt, aber die Threads laufen noch, also befindet sich der Zombie-Status. Es ist bekannt, dass Threads unter Windows kaum zu stoppen sind, und wenn sie in einem unterbrechungsfreien Systemaufruf stecken, sind sie absolut nicht zu stoppen.

Die einzige Lösung besteht darin, Ihren Dienst besser zu gestalten, sodass die Threads möglicherweise angehalten werden und dieses Signal in der OnStop () - Methode des Dienstes festgelegt wird.

Die Threads sollten bei allen Systemaufrufen immer ein Timeout ausführen und ihre Stoppbedingung überprüfen, wenn das Timeout ausgelöst wird.

Die Alternative könnte darin bestehen, dass die OnStop () -Methode thread.Abort() zum Stoppen der Threads verwendet wird. Dies ist normalerweise eine schlechte Idee, da nicht bekannt ist, was der Thread tun könnte, wenn er gestoppt wird und in welchem ​​Zustand die Ressourcen, die er modifiziert, nach dem Abbruch sein werden (was außerdem möglicherweise ineffektiv ist).

Ich wusste gar nicht, dass es im modernen Windows einen unterbrechungsfreien Systemaufruf gibt. Welche Anrufe sind unterbrechungsfrei? Ich kann jetzt kein Crash-Dump erstellen, aber soweit ich mich erinnere, gibt es zwei Threads, von denen sich einer im `WaitForSingleObject'-Aufruf befindet und der andere auf Daten im Socket wartet. Sind beide nicht unterbrechbar? Wenn nicht, wie kann ich sie aufhalten? (Ich habe gerade 'Win32_Thread' gefunden und werde damit experimentieren.) George Sovetov vor 6 Jahren 0
Warten Sie, bis ein Semaphor ununterbrochen ist. Brich deine Threads nicht ab - füge allen Wartezeiten Timeouts hinzu. harrymc vor 6 Jahren 0
Leider habe ich keinen Zugriff auf den Quellcode. Hoffentlich wird der Anbieter es bald beheben. George Sovetov vor 6 Jahren 0
Nur der Anbieter kann dieses Problem lösen. Wenn Ihr Problem und seine Lösung jetzt klar sind, markieren Sie die Antwort möglicherweise als akzeptiert. harrymc vor 6 Jahren 0
Als ich "Win32_Thread" erwähnte, meinte ich, Threads extern zu beenden, nicht von einem Prozess, der beleidigt wurde. Es scheint aber, dass Threads von außen nicht beendet werden können. Zumindest hat Win32_Thread keine Methoden. (Ich stimme vollkommen zu, dass Threads ordnungsgemäß beendet werden und versuchen sollten, meine eigenen Apps auf diese Weise zu entwerfen.) George Sovetov vor 6 Jahren 0