Обнаружение приложения зависает

У меня есть очень большое, сложное (миллион + LOC) Приложение Windows, записанное в C++. Мы получаем горстку отчетов каждый день, что приложение заперлось и должно быть сильно закрыто.

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

Проблема обнаруживает, когда подвешивание происходит. До сих пор лучшим, который я могу придумать, является сторожевой поток (поскольку у нас есть доказательство, что фоновые потоки продолжают выполнять проблемы w/out), который периодически проверяет с помощью ping-запросов главное окно с пользовательским сообщением и подтверждает, что это обрабатывается своевременно. Это только получило бы поток GUI, зависает, но это, действительно кажется, где большинство их происходит. Если бы ответ не был получен в кадре настраиваемого времени, то мы получили бы память и дамп стека, и дали бы пользователю опцию продолжения ожидать или перезапуск приложения.

Кто-либо знает о лучшем способе сделать это, чем такой периодический опрос главного окна таким образом? Это кажется крайне неуклюжим, но я не видел альтернативы, которые будут работать над нашими платформами - Windows XP и Windows 2003 Server. Я вижу, что Vista имеет намного лучшие инструменты для этого, но к сожалению который не поможет нам.

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

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

7
задан Marc Paradise 16 December 2009 в 21:35
поделиться

4 ответа

The answer is simple: SendMessageTimeout!

Using this API you can send a message to a window and wait for a timeout before continuing; if the application responds before timeout the is still running otherwise it is hung.

3
ответ дан 7 December 2019 в 07:46
поделиться

One option is to run your program under your own "debugger" all the time. Some programs, such as GetRight, do this for copy protection, but you can also do it to detect hangs. Essentially, you include in your program some code to attach to a process via the debugging API and then use that API to periodically check for hangs. When the program first starts, it checks if there's a debugger attached to it and, if not, it runs another copy of itself and attaches to it - so the first instance does nothing but act as the debugger and the second instance is the "real" one.

How you actually check for hangs is another whole question, but having access to the debugging API there should be some way to check reasonably efficiently whether the stack has changed or not (ie. without loading all the symbols). Still, you might only need to do this every few minutes or so, so even if it's not efficient it might be OK.

It's a somewhat extreme solution, but should be effective. It would also be quite easy to turn this behaviour on and off - a command-line switch will do or a #define if you prefer. I'm sure there's some code out there that does things like this already, so you probably don't have to do it from scratch.

3
ответ дан 7 December 2019 в 07:46
поделиться

Предложение:

Предполагая, что проблема связана с блокировкой, вы можете сбросить свои состояния мьютексов и семафоров из сторожевого потока. Немного поработав (проследив график вызовов), вы сможете определить, как вы попали в тупик, какие пути вызовов взаимно блокируют и т. Д.

1
ответ дан 7 December 2019 в 07:46
поделиться

While a crashdump analysis seems to provide a solution for identifying the problem, in my experience this rarely bears much fruit since it lacks sufficient unambiguous detail of what happened just before the crash. Even with the tool you propose, it would provide little more than circumstantial evidence of what happened. I bet the cause is unprotected shared data, so a lock trace wouldn't show it.

The most productive way of finding this—in my experience—is distilling the application's logic to its essence and identifying where conflicts must be occurring. How many threads are there? How many are GUI? At how many points do the threads interact? Yep, this is good old desk checking. Leading suspect interactions can be identified in a day or two, then just convince a small group of skeptics that the interaction is correct.

0
ответ дан 7 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

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