Ищете идеи для отладки сложного запуска Windows службы Гремлин - PullRequest
11 голосов
/ 15 января 2012

За последние несколько месяцев я получил несколько отчетов от QA об одном из наших сервисов.Изучив дамп зависания с помощью WinDbg, я каждый раз обнаруживал одно и то же: критический раздел блокировки загрузчика заблокирован, но нигде не найден собственный поток.Поскольку поток пропал, и единственная трасса, которую я вижу, - это глобальный критический раздел, который он оставил позади, я не вижу, какой код выполнялся в потоке потока, или даже из какой библиотеки DLL этого потока, он может даже не быть одним изнаш (т. е. сторонний поставщик).

Эта проблема носит весьма спорадический характер, ее можно увидеть только 3-4 раза за последние 6 месяцев, что происходит естественным образом в условиях дикой природы.В остальное время сервис работает отлично.Так что это заставляет меня поверить, что это какое-то время / гонка.

Недавно я решил взять это на себя, чтобы выяснить это.Я настраиваю машину с помощью скрипта WinTask, который постоянно запускает / останавливает указанную службу.Хорошая новость заключается в том, что в течение 5-6 часов я могу воспроизвести проблему.

Теперь перейдем к следующей части: как ее изолировать?

Это то, что я пробовал до сих пор:

  1. использовал поле «отладчик» в настройках образа gflags для автоматического запуска сервиса под cdb при каждом его запуске.До сих пор это работало в течение двух дней и никогда не зависало, поэтому я думаю, что отладчик внес достаточно изменений времени, чтобы сделать проблему невидимой.

  2. Проверенный загрузчик приложений и настроилПроцесс запуска с этим.Нашел совершенно несвязанную ошибку, в которой мы создали временную переменную CComBSTR, присвоили ее переменной VARIANT и передали вариант в вызов функции, даже если CComBSTR долго удалял выделенную строку к этому моменту.Не верьте, что эта ошибка связана с тем, что строка доступна только для чтения, а поток, на котором она работает, не тот, который умирает.

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

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

Если что-то не случится в выходные, моим следующим шагом будет отключение всех отладчиков, возврат к хранилищу и взломать один из DllMains, чтобызаписывать события THREAD_ATTACH / THREAD_DETACH.По крайней мере, я смогу перехватить поток, который умирает, когда он создается.Это может пролить свет.

Ответы [ 4 ]

2 голосов
/ 15 января 2012

Я мог бы попробовать подключить отладчик ядра, а затем запустить процесс в Appilcation Verifier. AV имеет проверки на выгрузку DLL, в то время как он содержит CS и завершающие потоки, которые все еще содержат CS. Таким образом, эти точки останова должны сработать в отладчике ядра, а затем, надеюсь, вы сможете поймать его в действии. Надеюсь, что запуск его под KD не замедлит его, как это делает отладчик пользовательского режима.

1 голос
/ 17 января 2012

Оказывается, я был ближе к решению, чем я думал. С сервисом, работающим под управлением cdb, который изменил время, а затем запустил его с помощью верификатора приложения, который еще больше изменил время (включение кучи страниц замедляет выделение ресурсов), секретный компонент, который я пропустил, был prime95.exe. Запуск prime95.exe с приоритетом выше обычного, действительно облажался в любое время, которое я пытался не изменить, но это заставило проблему обнаружиться менее чем за 15 минут.

Причина:

Сторонний SDK для получения данных с аппаратных плат. Когда наш сервис запускается, мы запрашиваем различные компоненты захвата для их возможностей. После выполнения запроса мы освобождаем экземпляр компонента. По-видимому, эта одна DLL запустила отдельный поток, который получил блокировку загрузчика, а затем приступил к куче инициализации в этом потоке. Если в течение этого времени наш запрос возможностей будет выполнен, и мы выпустим компонент, их код вызовет TerminateThread () в этом другом потоке, оставляя блокировку загрузчика навсегда заблокированной. Prime95 замедлил все настолько, что я смог поймать это состояние гонки и получить следующее сообщение остановки верификатора:

=======================================
VERIFIER STOP 00000200: pid 0x1A8C: Thread cannot own a critical section. 

0000091C : Thread ID.
77E17340 : Critical section address.
00000000 : Critical section debug information address.
00000000 : Critical section initialization stack trace.

Самое забавное, что этот поток «исчезал» без каких-либо исключений, поэтому отладчик даже не поймал бы первого шанса. Кто использует TerminateThread ????

Спасибо всем за предложения и поддержку. Вообще-то, я с нетерпением ждал поездки во время обеда в Radioshack, чтобы купить последовательный кабель, а затем провел несколько дней, играя с KD. Похоже, что придется подождать до следующего раза:)

0 голосов
/ 17 января 2012

Я бы попробовал неинвазивный отладчик и посмотрел, как это происходит, хотя вы не сможете остановить процесс, вы должны видеть любые сообщения отладки, а также любые потоки, которые запускаются и останавливаются, иэто должно оказать минимальное влияние на производительность процесса.Я обычно использую windbg для своей отладки, но я думаю, что cbd также имеет аналогичные опции.Это, скорее всего, позволит вам увидеть, что происходит в процессе, и, по крайней мере, начать помогать сужать его.Одна вещь, которую вы, возможно, захотите сделать, это перенаправить вывод (.logopen в windbg), чтобы убедиться, что ничего не выходит за пределы вашего буфера.

0 голосов
/ 15 января 2012

Несколько случайных идей: если присоединение отладчика не помогает, то следующим шагом будет инструментарий (ваш последний пункт). Но как поток может просто умереть, не останавливая весь процесс, вы где-то ловите исключения? Вы также можете войти туда. Вы также можете настроить WinDbg на прерывание всех исключений первого случая, если это поможет. Окно вывода WinDbg в любом случае покажет исключения первого шанса, даже если вы не сломаете.

...