Контрольный механизм отчетов о сбоях, когда мое приложение зависает на компьютере клиента

StackOverflow https://stackoverflow.com/questions/755847

Вопрос

Я работаю с несколько ненадежным приложением (Qt/windows), частично написанным для нас третьей стороной (просто пытаюсь переложить вину на него).Их последняя версия более стабильна.Вроде, как бы, что-то вроде.Мы получаем меньше сообщений о сбоях, но получаем много сообщений о том, что он просто зависает и больше не возвращается.Обстоятельства различны, и с той небольшой информацией, которую мы можем собрать, мы не смогли воспроизвести проблемы.

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

  • Как сторожевой таймер узнает, что процесс завис?Предположительно, мы настраиваем приложение так, чтобы оно периодически сообщало сторожевому таймеру «все окей», но где нам это сделать, чтобы это гарантированно происходило достаточно часто, но вряд ли находилось на пути кода, на котором приложение оказывается в момент его запуска? заперто.

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

Это было полезно?

Решение

Вам нужна комбинация мини-дампа (используйте DrWatson для его создания, если вы не хотите добавлять свой собственный код создания мини-дампа) и пользовательского дампа, чтобы инициировать создание мини-дампа при зависании.

Особенность автоматического обнаружения зависания заключается в том, что трудно решить, когда что-то зависло, а когда оно просто медленное или заблокировано ожиданием ввода-вывода.Лично я предпочитаю позволить пользователю намеренно завершать работу приложения, когда он думает, что оно зависло.Помимо того, что это намного проще (мои приложения не часто зависают, если вообще зависают :)), это также помогает им «быть частью решения».Им это нравится.

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

Во-вторых, получить пользовательский дамп который позволяет создавать дампы, и инструкции за настройку генерации дампов

Когда у вас есть дамп, откройте его в WinDBG, и вы сможете проверить все состояние программы, включая потоки и стеки вызовов, регистры, память и параметры функций.Я думаю, вам будет особенно интересно использовать "~*кп" в Windbg для получения стека вызовов каждого потока и команда "!locks" для отображения всех блокирующих объектов.Я думаю, вы обнаружите, что зависание происходит из-за взаимоблокировки объектов синхронизации, которую будет трудно отследить, поскольку все потоки имеют тенденцию ожидать вызова WaitForSingleObject, но посмотрите дальше в стеки вызовов, чтобы увидеть потоки приложения (скорее чем «структурные» потоки, такие как фоновые уведомления и сетевые процедуры).Как только вы сузите их, вы сможете увидеть, какие вызовы были сделаны, возможно, добавьте в приложение некоторые инструменты для ведения журнала, чтобы попытаться предоставить вам больше информации, готовой к следующему сбою.

Удачи.

Пс.Быстрый гугл напомнил мне вот это: Отладка взаимоблокировок.(CDB — это эквивалент Windbg для командной строки)

Другие советы

Вы можете использовать ADPlus из инструментов отладки Microsoft для Windows, чтобы выявить зависания.Он подключится к вашему процессу и создаст дамп (мини-или полный), когда процесс зависнет или выйдет из строя.

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

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

Я думаю, что отдельное приложение для наблюдения, скорее всего, создаст больше проблем, чем решит.Вместо этого я бы предложил вам сначала создать обработчики для создания минидампов при сбое приложения, а затем добавить в приложение сторожевой поток, который НАМЕРЕННО выйдет из строя, если приложение выйдет из строя.Преимущество сторожевого потока (по сравнению с другим приложением) заключается в том, что сторожевому таймеру должно быть проще узнать наверняка, что приложение сошло с рельсов.

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

В CodeProject есть кое-что о Мини-свалки, что может быть полезным примером.MSDN также содержит дополнительную информацию о них.

Не беспокойтесь о сторожевом псе.Подпишитесь на отчеты об ошибках Windows от Microsoft (winqual.microsoft.com).Они соберут для вас трассировки стека.На самом деле, вполне вероятно, что они уже делают это сегодня;они не делятся ими, пока вы не зарегистрируетесь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top