За последние несколько месяцев я получил несколько отчетов от QA об одном из наших сервисов.Изучив дамп зависания с помощью WinDbg, я каждый раз обнаруживал одно и то же: критический раздел блокировки загрузчика заблокирован, но нигде не найден собственный поток.Поскольку поток пропал, и единственная трасса, которую я вижу, - это глобальный критический раздел, который он оставил позади, я не вижу, какой код выполнялся в потоке потока, или даже из какой библиотеки DLL этого потока, он может даже не быть одним изнаш (т. е. сторонний поставщик).
Эта проблема носит весьма спорадический характер, ее можно увидеть только 3-4 раза за последние 6 месяцев, что происходит естественным образом в условиях дикой природы.В остальное время сервис работает отлично.Так что это заставляет меня поверить, что это какое-то время / гонка.
Недавно я решил взять это на себя, чтобы выяснить это.Я настраиваю машину с помощью скрипта WinTask, который постоянно запускает / останавливает указанную службу.Хорошая новость заключается в том, что в течение 5-6 часов я могу воспроизвести проблему.
Теперь перейдем к следующей части: как ее изолировать?
Это то, что я пробовал до сих пор:
использовал поле «отладчик» в настройках образа gflags для автоматического запуска сервиса под cdb при каждом его запуске.До сих пор это работало в течение двух дней и никогда не зависало, поэтому я думаю, что отладчик внес достаточно изменений времени, чтобы сделать проблему невидимой.
Проверенный загрузчик приложений и настроилПроцесс запуска с этим.Нашел совершенно несвязанную ошибку, в которой мы создали временную переменную CComBSTR, присвоили ее переменной VARIANT и передали вариант в вызов функции, даже если CComBSTR долго удалял выделенную строку к этому моменту.Не верьте, что эта ошибка связана с тем, что строка доступна только для чтения, а поток, на котором она работает, не тот, который умирает.
Я делаю этот пост на тот случай, если вы, ребята, могли бы подумать о чем-то, что я не рассматриваю.
Я думал, что была утилита для Windows, которая искусственно помещала нагрузкуна процессоре и делал другие вещи, чтобы всплыли условия гонки, и я думал, что верификатор приложений сделал такую вещь, но, очевидно, это не так.Кто-нибудь знает, о чем я говорю, или я просто мечтал об этом?
Если что-то не случится в выходные, моим следующим шагом будет отключение всех отладчиков, возврат к хранилищу и взломать один из DllMains, чтобызаписывать события THREAD_ATTACH / THREAD_DETACH.По крайней мере, я смогу перехватить поток, который умирает, когда он создается.Это может пролить свет.