пятница, 13 июля 2012 г.

Заметки по багфиксу

Во время работы над большим проектом, я усвоил несколько правил для более-менее эффективного багфикса. Собственно небольшой список:
  1. Постарайтесь добиться максимального процента воспроизведения баги. Как правило, проще воспроизвести ошибку в логике, чем ошибку нехватки ресурсов.
  2. Во время поиска причины ошибки, как правило нет смысла в простом трейсе кода, лучше воспользоваться подходящим методом диагностирования для соответсвующего типа ошибки.
  3. Перед попыткой исправить ошибку, всегда следует понять как работает код, в котором она выявлена. Так же не следует делать поспешных выводов на счет причины, лучше хотя бы один раз убедиться, что это именно то, что искали, а не какая-нибудь статистическая погрешность или просто слабо документированный case.
  4. Следите, что бы не было регрессий после фикса.
  5. В больших проектах нельзя одному уследить за потоком изменений. При обсуждении уже существуюшей имплементации гораздо лучше сверяться с кодом, чем доверять чужому мнению. Вас могут ввести в заблуждение.
  6. Нельзя слепо доверять незнакомому коду, постарайтесь проанализировать его, если он как-то может участвовать при удачном воспроизведении баги.
  7. Если столкнулись с нехватой памяти в программе, используеющей JVM или .NET, то есть смысл выгрузить список объектов и попробовать найти там самые тяжелые. Если из этого плоского списка причину не удалось обнаружить, то можно попробовать составить таблицу объектов с отображением их колличества. Таким образом, мне часто удавалось находить memory leaks из-за того, что при нормальной работе приложения, количество некоторых объектов не может превышать некий предел.
  8. Частые старты garbage collector не всегда означают нехватку памяти, он так же может стартовать когда используется слишком много объектов или исчерпывается количетсво доступных хэндлов для использования некоторого ограниченного ресурса, например большое количество открытых файлов.
  9. Если не удается уменьшить количество создаваемых объектов, то можно попробовать их переиспользовать.
  10. При проблемах с производительностью кода, в первую очередь следует смотреть в профайлер и только потом пытаться оптимизировать. Совет конечно очевидный, но некоторые пытаются угадать источник проблемы и тратят время впустую.
  11. Если использование профайлера затруднено, то есть смысл использовать для анализа лог с таймингами. Только не следует забывать, что I\O-операции могут повлиять на время исполнения кода. Если есть возможность, то следует использовать промежуточный буффер или сбрасывать дамп логов только после завершения работы исследуемого кода.
  12. Проблема "состояния гонки" между несколькими потоками следует анализировать в максимально приближенном окружении, в котором баг был найден. На воспроизводимость баги могут влиять как время исполнения отдельных блоков кода, так и разница во времени операиций ввода-вывода. Всегда следует контролировать в контексте какого потока может исполняться код.
  13. Не следует закрывать глаза на не исправленные баги, всегда должен быть способ их регистрации.
  14. В конце проекта всегда остаются самые плохо воспроизводимые и тяжело поддающиеся исправленю баги, не следует забывать об этом. Подобные баги следует начинать выделять уже в начале-середине проекта. Обычно их можно заметить по большим интервалам времени с моментам регистрации и проблемам с их воспроизведением.
  15. Всегда следует учитывать, что проблема может быть не в софте, а в железе.

Пока это только то, что всплыло в моей памяти за вечер. Буду стараться дополнять\обновлять список по мере возможностей. Так же буду рад каким-либо замечаниям.

2 комментария: