Подтвердить что ты не робот

Обнаружение взаимоблокировок в приложении С#

Возможный дубликат:
С#/.NET инструмент анализа для поиска условий гонки/тупиков

Я отлаживаю приложение, которое, как я подозреваю, заходит в тупик и висит. Однако это происходит только каждые несколько дней, и это никогда не происходит на моем компьютере, поэтому я не могу подключить к нему отладчик. Существуют ли какие-либо утилиты или методы, которые я могу использовать для запроса запущенного приложения и выяснения того, какие методы/блокировки/все, за что он заблокирован?

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

4b9b3361

Ответ 1

Вместо того, чтобы использовать обычный подход lock и Monitor.Enter для блокировки некоторых данных, вы также можете использовать структуру TimedLock. Этот TimedLock генерирует исключение, если блокировка не может быть получена своевременно, и она также может дать вам предупреждение, если у вас есть блокировки, которые вы не выпустили.

Эта статья Ian Griffiths может помочь.

Ответ 2

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

  • Когда приложение зависает, скопируйте файлы WinDbg на компьютер.
  • Подключить WinDbg к процессу или использовать ADPlus, чтобы получить зависающую дампу процесса. Если вы выберете ADPlus, вы затем загрузите дамп в WinDbg.
  • Из WinDbg вы загружаете файл sos.dll, чтобы вы могли проверить управляемый код.
  • Команда !threads покажет вам все потоки в приложении и команду !clrstack, покажет вам, что они делают. Используйте ~e!clrstack, чтобы сбросить стек вызовов всех потоков. Ищите призывы к методам ожидания, поскольку они указывают на блокировку.
  • Команда !syncblk предоставит вам информацию о том, какие потоки содержат разные блокировки.
  • Чтобы узнать, что блокирует данный поток, пытается переключиться на поток и проверить объекты стека (!dso). Отсюда вы сможете найти блокировку, которую пытается попытаться создать нить.

Уточнение: WinDbg не требует регулярной установки. Просто скопируйте файлы. Кроме того, если вы берете дамп зависания, вы можете продолжить отладку на другом компьютере, если это необходимо.

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

Ответ 3

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

Ответ 5

У вас действительно есть очень интересная проблема. Есть несколько вещей, которые вы можете сделать:

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

Использовать FSP: Определите свою многопоточную систему, используя FSP. Таким образом, вы сможете создать конечный автомат процесса, который вы можете пройти, чтобы найти ошибку. Это решение является более математическим решением.

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

Я действительно рекомендую прочитать эту книгу: Jeff Magee и Jeff Kramer: Concurrency: State Models and Java Programs, Wiley, 1999

Ответ 6

Это очень интересная проблема и боль, потому что это происходит только каждые несколько дней. Я нашел эту статью в CodeProject. Это может быть началом для вас.

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

Ответ 7

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