2009-04-16 6 views
4

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

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

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

  • Какая информация должна указывать сторожевой таймер, когда происходит авария? У Windows есть достойная debug api, поэтому я уверен, что все интересные данные доступны, но я не уверен, что было бы полезно для отслеживания проблем.

ответ

5

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

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

Во-первых, ознакомьтесь с классическим номером bugslayer article, касающимся аварийных сообщений и символов, который также содержит отличную информацию о том, что происходит с этими вещами.

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

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

Удачи.

Ps. Быстрый Google напомнил мне об этом: Debugging deadlocks. (CDB - эквивалент командной строки windbg)

1

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

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

В CodeProject есть кое-что из MiniDumps, что может быть полезным примером. MSDN имеет больше информации о них.

+0

Вам не нужно разбивать приложение, чтобы создать мини-карты. Вы можете вызвать MiniDumpWriteDump() в любое время. –

2

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

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

BTW, если вы нашли способ распознать повесить внутри и смогли свернуть процесс, вы можете зарегистрироваться с помощью Windows Error Reporting, чтобы дамп сбоя был отправлен вам (если пользователь разрешит его).

1

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