Windows убивает сервис, который не отвечает на сигналы?

350
George Sovetov

У меня есть служба, которая работает как Local Systemи отказывается иногда останавливаться.

Сервисный процесс получает сигнал завершения, выполняет очистку, но несколько потоков продолжают работать из-за ошибки.

SCM сообщает в журнал событий с идентификатором 7011:

Время ожидания (30000 миллисекунд) было достигнуто при ожидании ответа транзакции от ... службы.

После этого службы отображаются как остановленные в окне «Службы» в консоли управления и в WMI.

Но как Windows работает со службой, если она не прекращает работу? Я не могу перезапустить службу: процесс запуска старой службы все еще блокирует файлы и привязан к портам.

Я ожидаю, что Windows убьет процесс, который не отвечает, но я не могу найти какую-либо документацию или настройки по этому поводу.

30000 мсек, кажется, взято с HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ServicesPipeTimeout( https://support.microsoft.com/en-us/help/839803/the-windows-trace-session-manager-service-does-not-start-and-event-id ), Но через 30 секунд я получаю только событие, процесс все еще там.

Согласно аварийному дампу, основной поток был прерван, и в некоторых есть несколько потоков, ожидающих на сокете WaitForSingleObject.

Мы уже сообщили об ошибке поставщику, и он пытается ее исправить. Но в основном вопрос в том, что делать, чтобы убить этот процесс, можно ли его очистить без перезагрузки.

2
Ваш вопрос противоречит основной проблеме, почему вы не можете перезапустить его. Существует заблокированное условие, что сервисный контроллер обычно ожидает корректного завершения процессов + потоки, но это не так. Таким образом, вы столкнулись с тупиковой ситуацией, и в этом случае служба ожидает установленной продолжительности, прежде чем отказаться. Если вы хотите перезапустить службу, вам нужно убить процессы вручную. Если вы хотите исправить это в долгосрочной перспективе, вам необходимо связаться с поставщиком программного обеспечения. Если вам нужен более глубокий анализ, загрузите procmon и procxp для более подробной диагностики или дамп и отладку thepip3r 6 лет назад 1
@ thepip3r Спасибо за предложение. Об ошибке уже сообщалось. George Sovetov 6 лет назад 0

1 ответ на вопрос

2
harrymc

Возможно, ваш сервис остановлен, но потоки все еще работают, поэтому он находится в состоянии зомби. Общеизвестно, что в Windows трудно остановить потоки, и если они застряли в непрерывном системном вызове, их невозможно остановить.

Единственное решение состоит в том, чтобы лучше спроектировать ваш сервис, чтобы потоки могли сигнализировать об остановке, и этот сигнал устанавливается в методе OnStop () сервиса.

Потоки должны всегда превышать время ожидания для всех системных вызовов и проверять состояние их остановки, когда время ожидания срабатывает.

Альтернативой может быть использование метода OnStop () для thread.Abort() остановки потоков. Обычно это плохая идея, потому что неизвестно, что может делать поток, когда остановлен, и в каком состоянии будут ресурсы, которые он изменяет после прерывания (что, кроме того, может быть неэффективным).

Я даже не знал, что есть бесперебойный системный вызов в современной Windows. Какие звонки бесперебойны? Сейчас я не могу сделать аварийный дамп, но, насколько я помню, есть два потока, один из которых находится в вызове WaitForSingleObject, а другой ожидает данных в сокете. Являются ли они оба непрерывными? Если нет, то как их остановить? (Я только что нашел `Win32_Thread` и поэкспериментирую с ним.) George Sovetov 6 лет назад 0
Ожидание семафора может быть бесперебойным, ожидание сети, безусловно, есть. Не прерывайте свои темы - добавьте тайм-ауты ко всем ожиданиям. harrymc 6 лет назад 0
К сожалению, у меня нет доступа к исходному коду. Надеюсь, продавец исправит это в ближайшее время. George Sovetov 6 лет назад 0
Только продавец может решить эту проблему. Если ваша проблема и ее решение теперь ясны, вы можете пометить ответ как принятый. harrymc 6 лет назад 0
Когда я упоминал `Win32_Thread`, я имел в виду прекращение потоков извне, а не из-за нарушения процесса. Но кажется, что потоки не могут быть прекращены извне. По крайней мере, `Win32_Thread` не имеет методов. (Я полностью согласен с тем, что потоки должны завершаться изящно и пытаться создавать свои собственные приложения таким образом.) George Sovetov 6 лет назад 0

Похожие вопросы