Какой совет для отладки действительно трудно отследить ошибки?


Большинство ошибок довольно просты, легко воспроизводимы и легко отлаживаются. Что вы делаете, когда сталкиваетесь с теми, которые трудно или невозможно повторить под отладчиком, то есть одним из этих?

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

У нас уже есть система отчетов об ошибках, поэтому, если нам повезет и ошибка вызовет исключение, мы получим трассировку стека, но даже этого не всегда достаточно, потому что из стека не очевидно, например, как определенное значение оказалось нулевым (например). Это особенно верно, когда исключение возникает в рабочем потоке (что имеет место в большинстве случаев.

И тогда у вас есть такие это даже не создает исключений, это просто неожиданное поведение. Но это случается лишь в небольшом проценте случаев.

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

Очевидно, что прямых ответов нет, так как я не спрашиваю о конкретной ошибке, но каковы некоторые общие концепции принципы и тактика, чтобы идти дальше решать такого рода проблемы?

5 3

5 ответов:

Ну, я думаю, что часть этого должна быть рассмотрена при проектировании, что некоторые могут назвать "заботой предприятия" - включение половины приличного ведения журнала / трассировки и инструментария очень поможет в отладке (особенно с настраиваемой многословностью!). Даже добавление в приложение нескольких пользовательских счетчиков производительности иногда может помочь отладить условия гонки.. если вам приходится идти на крайности.

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

Наконец, наличие хорошей тестовой среды, в которой вы можете попытаться воспроизвести те же условия & erros, иногда очень помогает, даже если вам придется имитировать ее, а не воссоздавать физическую сеть компьютеров, например.

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

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

С большинством ошибок вы находите их после события, и вы исправляете их, пытаясь воссоздать обстоятельства. Простой баг = простой отдых.

Ключ к вашей проблеме-это возможность воссоздать обстоятельства. В такой сложной среде, как эта, я думаю, что единственный способ сделать это-взять каждую точку интерфейса, которая может потерпеть неудачу, и реализовать ведение журнала для этого интерфейса, т. е. дамп в файл и/или БД. Конечно, вы не хотите, чтобы это включалось все время, но вы должны кодировать это было в самом начале. Затем настройте тестовую среду, которая затем может управляться из данных журнала, таким образом, вы можете запускать и повторно запускать обстоятельства, пока не создадите ошибку заново, и тогда вы на 80% приблизитесь к ее решению.

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

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

И чтобы усилить эту мысль, не вносите никаких изменений, которые не упрощают дизайн.

Если подумать, многие паттерны для этого описаны в разделе "рефакторинг".

Систематическое ведение журнала может помочь:

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

  • Регистрируйте изменения внутреннего состояния, когда их трудно вывести из того, что происходит на интерфейсах.

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