2.15

Смотреть на английском

2.15 Отладка и устранение неполадок

Обзор и мотивация

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

Для большой команды разница дорога. Один трудный дефект может втянуть инженеров из нескольких сервисов, съесть часы дежурств и остановить выпуск. Когда каждый отлаживает по инстинкту, эти усилия не накапливаются, потому что никто не может воспроизвести или объяснить то, что пробовал кто-то другой. Когда команда разделяет метод (сначала воспроизвести, изолировать поиском, зафиксировать ошибку в падающем тесте, затем исправить), те же усилия превращаются в повторяемый процесс и растущий набор регрессионных тестов. Отладка тесно связана со стратегией тестирования (глава 2.4), с качеством программного обеспечения (глава 2.11) и с привычками конструирования (глава 2.9), делающими код диагностируемым с самого начала.

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

Ключевые принципы

  • Воспроизведите, прежде чем теоретизировать. Ошибка, которую нельзя вызвать по требованию, слух, а не дефект.
  • Отладка это проверка гипотез. Сформулируйте, во что верите, затем спроектируйте самый дешёвый эксперимент, способный доказать вашу неправоту.
  • Сначала прочтите ошибку и трассировку стека. Система обычно говорит, где сломалась, ещё до того, как вы изменили строку.
  • Ищите по пространству проблемы, а не сканируйте его. Делите подозреваемую область пополам на каждом шаге вместо чтения сверху вниз.
  • Сводите к минимуму. Урезайте случай, пока не останется только существенный триггер.
  • Одно изменение за раз. Правки наугад уничтожают свидетельство, которое сказало бы, какое изменение имело значение.
  • Зафиксируйте ошибку в падающем тесте до исправления. Исправление доказано, только когда этот тест зеленеет и остаётся зелёным.
  • Находите первопричину, а не ближайший симптом. Заплатка, скрывающая симптом, оставляет дефекту возможность вернуться.

Рекомендации

Надёжно воспроизведите дефект, прежде чем что-либо менять

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

Прочтите ошибку, журналы и трассировку стека, прежде чем трогать код

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

Изолируйте бинарным поиском по пространству проблемы

Не сканируйте код сверху вниз. Ищите в нём. Используйте бинарный поиск: найдите точку, где состояние ещё хорошее, и точку, где оно уже плохое, затем проверьте середину и повторяйте, деля подозреваемую область пополам каждый раз. Это превращает поиск по тысяче строк в десять вопросов. Когда регрессия появилась на диапазоне коммитов, примените ту же идею к истории с помощью бисекции: git bisect проходит диапазон коммитов, а вы отмечаете каждую ревизию хорошей или плохой, пока он не назовёт точное изменение, внёсшее дефект. Автоматизируйте проверку «хорошо или плохо», и бисекция запускается сама.

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

Как только вы можете вызвать ошибку, сожмите её. Минимальный воспроизводимый пример это наименьший ввод и путь кода, всё ещё падающий: убирайте данные, функции и шаги, пока любое дальнейшее удаление не заставит ошибку исчезнуть. Сведение не пустая работа; каждый устранённый вами элемент исключённая причина, поэтому минимальный случай часто указывает прямо на дефект. Когда ввод велик или структурирован, автоматизируйте сжатие с помощью дельта-отладки, алгоритма, систематически удаляющего куски падающего ввода, чтобы найти минимальное падающее подмножество. Небольшое самодостаточное воспроизведение ещё и лучший возможный отчёт об ошибке для передачи другой команде.

Инструментируйте журналами, затем используйте интерактивный отладчик

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

Напишите падающий тест, фиксирующий ошибку, до её исправления

Прежде чем писать исправление, напишите тест, падающий из-за ошибки. Это делает три вещи сразу: доказывает, что вы действительно понимаете причину, определяет, что именно значит «исправлено», и становится постоянным стражем. Затем сделайте исправление и смотрите, как тест зеленеет. Теперь этот тест входит в ваш набор как страж регрессионного тестирования, так что тот же дефект не может вернуться незамеченным. Эта практика напрямую связывает отладку со стратегией тестирования (глава 2.4): каждая решённая трудная ошибка оставляет набор сильнее, чем был, а нестабильный тест получает то же обращение (воспроизвести недетерминизм, затем защититься от него), а не аннотацию повтора.

Находите первопричину и держите анализ без поиска виноватых

Исправление симптома не исправление ошибки. Проследите отказ до истинного источника, спрашивая почему на каждом слое, пока не дойдёте до причины, которую можно устранить, а не замаскировать. Для дефектов, достигших эксплуатации, проводите анализ первопричин без поиска виноватых как часть управления инцидентами (глава 9.3): сосредоточьтесь на условиях системы и процесса, позволивших ошибке выйти и выжить, никогда на человеке, написавшем строку. Обвинение загоняет информацию вглубь, а отладка работает на информации. Результат и исправление, и изменение того, как этот класс дефектов будет ловиться раньше в следующий раз.

Компромиссы: плюсы и минусы

ПодходПлюсыМинусы
Журналирование и инструментацияРаботает в эксплуатации и распределённых системах; фиксирует поведение во времениШум, стоимость и расползание журналов; может возмущать ошибки времени
Интерактивный отладчикТочное исследование живого состояния; быстро для локальных ошибокБесполезен в ограниченной или изолированной эксплуатации; может скрывать ошибки конкурентности
Дисциплина «сначала воспроизвести»Превращает догадки в измерение; позволяет падающий тестМедленно заранее; некоторые ошибки действительно трудно вызвать
Бинарный поиск и бисекцияБыстрая изоляция даже в незнакомом кодеНужна надёжная проверка «хорошо или плохо»; трудно, когда ошибки взаимодействуют
Сжатие дельта-отладкойАвтоматически сжимает огромные вводы до триггераСтоимость настройки; предполагает детерминированность отказа
Исправить симптом сейчасБыстро восстанавливает сервис под давлениемОставляет первопричину для возврата; копит долг

Основное напряжение это скорость против уверенности. При инциденте в эксплуатации может понадобиться сначала остановить кровотечение (откат или заплатка симптома), чтобы восстановить сервис, и это законно. Ошибка в том, чтобы остановиться на этом. Разрешите напряжение, разделив две работы: быстро смягчите, чтобы защитить пользователей, затем воспроизведите, найдите первопричину и добавьте регрессионного стража, прежде чем считать дефект закрытым. Исправление симптома без продолжения это ошибка, с которой вы согласились встретиться снова.

Вопросы для обсуждения с командой

  1. Когда кто-то сталкивается с трудной ошибкой, что он делает первым: воспроизводит или гадает? Честный ответ показывает, есть ли у вашей команды общий метод или комната, полная частного фольклора. Попросите людей вслух рассказать о последнем трудном дефекте: получили ли они сначала надёжное воспроизведение или начали менять код и перезапускать? Команда, воспроизводящая сначала, может передавать ошибку между людьми, потому что воспроизведение путешествует; команда, гадающая, не может, потому что каждая попытка невоспроизводима. Это важнее по мере роста команды, поскольку человек, видящий симптом, всё чаще не тот, кто может его исправить. Если умолчание гадание, согласуйте «сначала воспроизвести» как норму и сделайте чистое воспроизведение входным билетом в тикет ошибки.

  2. Возвращаются ли ошибки, которые мы исправляем, и узнали бы мы, если бы вернулись? Дефект, который возвращается, это дефект, чья первопричина так и не была устранена, а исправление не охранялось тестом. Возьмите ваш последний квартал инцидентов и повторно открытых тикетов и сосчитайте, сколько было повторами или близкими родственниками прежних ошибок. Каждый повтор свидетельство того, что команда залатала симптом, пропустила падающий тест или слишком рано остановила анализ первопричин. Исправление в правиле: ни одна ошибка не закрыта, пока тест, падающий на старом поведении, не проходит на новом и не входит в набор. Принесите одну недавнюю повторяющуюся ошибку и спросите, какой страж поймал бы её, потому что этого стража вам и не хватало.

  3. Можем ли мы вообще отлаживать наши эксплуатационные системы с учётом того, как нам разрешено их трогать? В корпоративной и особенно государственной среде часто нельзя подключить отладчик, воспроизвести с реальными данными и изменить работающую систему без следа аудита. Если вашей единственной техникой отладки служит локальный интерактивный отладчик, вы слепы именно там, где живут самые трудные ошибки. Спросите, какое свидетельство эксплуатационный сбой на самом деле оставляет: структурированные журналы, распределённые трассировки (глава 9.2), дампы памяти или воспроизводимые артефакты сборки. Решите сейчас, что нужно фиксировать по умолчанию, чтобы будущий инцидент был диагностируем, потому что нельзя добавить инструментацию к сбою, который уже произошёл. В регулируемой среде убедитесь, что тот же след удовлетворяет и вашим обязательствам по аудиту.

  4. Когда инцидент в эксплуатации вынуждает быстро остановить кровотечение, как мы убеждаемся, что первопричина всё же будет найдена потом? При инциденте откат или заплатка симптома правильный первый ход для защиты пользователей, но опасность в том, что тикет закрывается в момент возвращения сервиса, а лежащий в основе дефект так и не диагностируется. Для большой команды именно здесь долг копится невидимо, потому что тот же класс отказа всплывает в другом сервисе и у другого дежурного инженера месяцы спустя. Принесите ваши последние несколько инцидентов первой серьёзности и проверьте каждый: следовали ли за смягчением воспроизведение, анализ первопричин и регрессионный страж или история заканчивалась на «сервис восстановлен»? Согласуйте явное правило, что смягчённый инцидент остаётся открытым, пока первопричина не понята и не охраняется, и назовите, кто отвечает за это доведение до конца. В корпоративной и государственной среде привяжите это к вашему процессу управления инцидентами (глава 9.3), чтобы пост-инцидентное ревью было обязательным проверяемым шагом, а не любезностью, срывающейся, когда начинается следующий пожар.

  5. Какую часть сбоя мы действительно можем восстановить постфактум и кто решил, что мы фиксируем по умолчанию? Нельзя прикрепить инструментацию к сбою, который уже произошёл, поэтому диагностируемость любого инцидента определяется заранее журналами, трассировками, метриками и дампами, которые вы выбрали испускать. Противоположное соображение это стоимость и шум: события с высокой кардинальностью и полная трассировка не бесплатны, а избыточное журналирование хоронит сигнал, раздувая хранилище и, в регулируемых контекстах, ваш риск хранения данных. Принесите реальный недавний инцидент и спросите, какое свидетельство он оставил, затем пройдите назад к тому, что вы хотели бы зафиксировать, и во что обошлось бы это сохранять. Решите намеренно, какие сигналы включены по умолчанию, а какие выборочны или по запросу, и запишите это решение, чтобы оно было политикой, а не случайностью. Для корпоративной или государственной системы добавьте, кто отвечает за этот бюджет наблюдаемости и удовлетворяет ли зафиксированный след также обязательствам по аудиту, приватности и размещению данных.

  6. Воспринимаем ли мы отладку как преподаваемый, измеримый навык или новые инженеры впитывают её осмосом? Отладке можно научиться, но большинство команд никогда не обучают ей явно, поэтому младшие наследуют любой фольклор, оказавшийся ближе, а метод «сначала воспроизвести» распространяется неравномерно или вовсе нет. Напряжение в том, что намеренное обучение (парная работа над трудными ошибками, написание выводов после инцидентов, отслеживание метрик) стоит времени старших, которое всегда кажется нужным в другом месте. Принесите на обсуждение два числа: вашу долю повторных дефектов и время диагностики, потому что если вы не можете их измерить, вы не можете сказать, улучшается ли ваш метод или деградирует. Подумайте, включает ли адаптация настоящее упражнение по отладке и питают ли выводы по первопричинам более раннее обнаружение. В большой или государственной организации документированная измеряемая практика отладки становится ещё и свидетельством инженерной строгости, которое аудиторы, регуляторы и надзорные органы всё чаще ожидают увидеть.

Взгляд по секторам

Стартап. С горсткой инженеров и без запаса ваша цель сделать ошибки дешёвыми для воспроизведения и невозможными для забывания, а не строить тяжёлый процесс. Опирайтесь на git bisect, быстрое локальное воспроизведение и один падающий тест на исправленную ошибку, потому что эта привычка стоит минуты и не даёт заново платить за один и тот же дефект, пока вы пытаетесь выпускать. Пропустите формальные постмортемы, но никогда не пропускайте регрессионный тест: это единственный артефакт, достаточно малый, чтобы всегда себе позволить, и достаточно ценный, чтобы всегда хранить.

Малый бизнес. У вас, вероятно, нет выделенного специалиста по надёжности или наблюдаемости и ограничен бюджет на инструменты, поэтому отдавайте предпочтение тому, что уже даёт ваш стек: читаемым трассировкам стека, структурированным журналам и трассировке, встроенной во фреймворки и хостинговые сервисы, которые вы купили. Оценивая новую платформу, взвешивайте, насколько диагностируемыми она делает сбои, потому что дешёвый инструмент, скрывающий, что пошло не так, стоит вам гораздо больше времени на догадки, чем сэкономила лицензия. «Сначала воспроизвести» и «одно изменение за раз» бесплатные дисциплины, окупающиеся быстрее всего, когда ни у кого нет лишних часов.

Крупная организация. Ваши трудные ошибки пересекают границы сервисов и команд, поэтому человек, видящий симптом, редко владеет причиной, и общий метод важнее навыка любого отдельного человека. Стандартизируйте «сначала воспроизвести», изоляцию бинарным поиском, падающий тест до исправления и постмортемы без поиска виноватых по командам и вкладывайтесь в распределённую трассировку (глава 9.2), чтобы один запрос можно было проследить через сервисы. Управляйте отладкой как измеряемой способностью: отслеживайте долю повторных дефектов и время диагностики и возвращайте выводы по первопричинам в более раннее обнаружение, чтобы тот же класс отказа не гулял по карте ваших сервисов.

Государственный сектор. Правила закупок, ограниченные среды и публичная подотчётность определяют, как вам вообще можно отлаживать. Часто нельзя подключить отладчик к эксплуатации или скопировать данные граждан на ноутбук, поэтому проектируйте диагностику по тому, что разрешено: воспроизводимые сборки, синтетические записи в изолированном анклаве и структурированные журналы и трассировки, фиксируемые по умолчанию. Записывайте каждый диагностический шаг и каждое изменение в след аудита и требуйте от поставщиков раскрывать достаточно телеметрии и воспроизводимости сборки, чтобы вы могли расследовать сбои независимо, а не полагаться на слово поставщика.

Примеры

Стартап. Команда из четырёх инженеров постоянно видит сбой оформления заказа у части пользователей, но никогда в тестах. Вместо догадок один инженер получает надёжное воспроизведение, повторяя точное содержимое падающего запроса, затем читает трассировку стека, которую они игнорировали, и она указывает на вызов разбора даты. Быстрый git bisect по коммитам недели называет изменение, переключившее библиотеку дат. Они пишут падающий тест с проблемной временной меткой, исправляют разбор, видят, как тест зеленеет, и оставляют его в наборе. Всё расследование занимает полдня, потому что они воспроизвели до теоретизирования, а ошибка никогда не возвращается.

Крупная организация. Платёжная платформа видит прерывистые тайм-ауты, которые не может объяснить ни одна команда, потому что симптом проявляется в оформлении заказа, а причина живёт тремя сервисами дальше. Дежурные инженеры используют распределённую трассировку (глава 9.2), чтобы проследить один падающий запрос через границы сервисов, и находят нижестоящий вызов, который иногда блокируется взаимно под конкурентной нагрузкой, классическое состояние гонки, где результат зависит от неудачного взаимного времени потоков. Они воспроизводят его нагрузочным тестом, фиксируют в падающем интеграционном тесте, исправляют блокировки и проводят постмортем без поиска виноватых (глава 9.3), добавляющий отрезок трассировки и оповещение, чтобы следующее возникновение было поймано за минуты, а не дни.

Государственный сектор. Агентство пособий ведёт систему обработки дел в изолированной среде, где инженеры не могут подключить отладчик к эксплуатации и скопировать данные граждан на ноутбуки. В сверке всплывает дефект расчёта. Команда отлаживает по тому, что среда допускает: структурированные журналы, воспроизводимая сборка, которую можно поднять в изолированном тестовом анклаве, и синтетические записи, воссоздающие падающий случай. Каждый диагностический шаг записывается в след аудита, исправление выходит с тестом «падает-затем-проходит» как свидетельством, а анализ первопричин питает новую проверку перед выпуском. Поскольку воспроизведение использовало синтетические данные, ни одна запись гражданина не покинула границу.

Бизнес-обоснование: мотивы, ROI и TCO

Отдача от дисциплинированной отладки измеряется инженерочасами, не потраченными на догадки, и дефектами, которые не повторяются. Недиагностированная прерывистая ошибка может съесть дни времени старших и повторяющиеся эскалации дежурств; метод «сначала воспроизвести» превращает это в ограниченную делегируемую задачу, а привычка падающего теста не даёт тому же дефекту выставить вам счёт снова в следующем квартале. По большой организации накопленный эффект того, что вы никогда заново не платите за одну и ту же ошибку, существенен, и он напрямую улучшает долю неудачных изменений и среднее время восстановления, которые руководство уже отслеживает.

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

Антипаттерны и ловушки

  • Отладка дробовиком: изменение многих вещей сразу, из-за чего даже исправление ничего не говорит о причине.
  • Исправление без воспроизведения: объявление победы над ошибкой, которую вы никогда не могли вызвать по требованию.
  • Игнорирование вывода ошибки: теории о причинах, которые трассировка стека уже исключила.
  • Заплатки симптомов: заглушение симптома, пока первопричина выживает и возвращается.
  • Расползание операторов вывода: разбросанный отладочный вывод, оставленный в коде и добавляющий шум вместо эксперимента, привязанного к гипотезе.
  • Пропуск регрессионного теста: исправление ошибки без стража, из-за чего она может тихо вернуться.
  • Повтор нестабильных тестов: сокрытие недетерминизма повторами вместо отладки лежащего в основе состояния гонки или гейзенбага, ошибки, меняющейся или исчезающей в момент попытки её наблюдать.
  • Постмортемы с обвинением: наказание автора, загоняющее вглубь информацию, от которой зависит отладка.

Модель зрелости

  • Уровень 1, Начальный: Отладка индивидуальный фольклор и реакция. Инженеры гадают, применяют правки дробовиком и перезапускают. Ошибки исправляются на симптоме, воспроизведения редки, а те же дефекты повторяются. Эксплуатация едва диагностируема, и никто не может передать ошибку другому, потому что ни одна попытка невоспроизводима.
  • Уровень 2, Развитие: Некоторые инженеры надёжно воспроизводят, читают трассировки стека и используют отладчики, но практика непоследовательна и различается от человека к человеку и от команды к команде. Журналирование есть, но шумное и неструктурированное. Исправления иногда выходят с падающим тестом, часто нет, а анализ первопричин происходит, только когда кто-то настаивает.
  • Уровень 3, Стандартизация: «Сначала воспроизвести», изоляция бинарным поиском, одно изменение за раз и падающий тест до исправления это документированные нормы команд, соблюдаемые по организации. Бисекция и сжатие дельта-отладкой обычная практика. В эксплуатации есть структурированное журналирование и трассировка (глава 9.2), а постмортемы без поиска виноватых (глава 9.3) стандартный ответ на каждый ускользнувший дефект.
  • Уровень 4, Управление: Практика отладки измеряется и контролируется относительно базовых значений. Доля повторных дефектов, время диагностики, число повторно открытых тикетов и доля исправлений, вышедших с регрессионным тестом, отслеживаются по командам и пересматриваются с периодичностью. Воспроизведение и завершение анализа первопричин рассматриваются как шлюзы, а не добрые намерения, и тренды относительно базового уровня определяют, куда вкладываться в инструменты, обучение и наблюдаемость.
  • Уровень 5, Оркестрация: Отладка преподаваемый навык, интегрированный с качеством (глава 2.11) и управлением инцидентами (глава 9.3), а весь цикл непрерывно адаптируется. Наблюдаемость заложена так, что большинство ошибок эксплуатации диагностируемо без отладчика, каждая решённая ошибка укрепляет набор регрессионных тестов, а выводы по первопричинам питают более раннее обнаружение, так что классы дефектов предотвращаются, а не диагностируются заново. Организация перебалансирует усилия по мере эволюции систем и режимов отказа, а доля повторных дефектов продолжает падать.

Идеи для обсуждения

  1. Какая доля ваших недавних ошибок была надёжно воспроизведена до того, как кто-то изменил код, и что эта доля говорит о вашем методе?
  2. Когда появляется регрессия, обращается ли ваша команда к бисекции или читает код вручную, пока кто-то не заметит?
  3. Насколько диагностируема ваша эксплуатационная система сегодня и что вы отдали бы за то, чтобы зафиксировать больше о сбое, который уже произошёл?
  4. Последовательно ли ваши исправления выходят с тестом «падает-затем-проходит» и если нет, где эта дисциплина ломается?
  5. Как вы обращаетесь с нестабильными тестами: отлаживаете недетерминизм или замазываете повторами?
  6. Преподаётся ли отладка новым инженерам намеренно или их оставляют впитывать фольклор осмосом?

Главные выводы

  • Отладка это проверка гипотез: надёжно воспроизведите, прочтите ошибку и трассировку стека, затем изолируйте бинарным поиском и бисекцией, а не сканированием.
  • Сведите отказ к минимальному воспроизводимому примеру, используя дельта-отладку для больших вводов, потому что каждый убранный элемент исключённая причина.
  • Подбирайте инструмент под ошибку: инструментация и трассировка для эксплуатации и распределённых систем (глава 9.2), интерактивные отладчики для локального расследования.
  • Напишите падающий тест, фиксирующий ошибку, до её исправления, чтобы исправление было доказано, а дефект навсегда охранялся (глава 2.4).
  • Находите и устраняйте первопричину, проводите постмортемы без поиска виноватых (глава 9.3) и воспринимайте отладку как обучаемый навык, а не фольклор.
  • Меняйте одну вещь за раз; правки дробовиком и заплатки симптомов уничтожают свидетельства и приглашают ошибку обратно.

Источники и дополнительное чтение

  • David J. Agans, Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems
  • Andreas Zeller, Why Programs Fail: A Guide to Systematic Debugging
  • Andreas Zeller and Ralf Hildebrandt, “Simplifying and Isolating Failure-Inducing Input” (the delta debugging algorithm)
  • Brian W. Kernighan and Rob Pike, The Practice of Programming (chapter on debugging)
  • Andrew Hunt and David Thomas, The Pragmatic Programmer (the chapters on debugging and assertions)
  • Steve McConnell, Code Complete: A Practical Handbook of Software Construction (the debugging chapter)
  • John Regehr, “Reducers Are Fuzzers” and related writing on test-case reduction
  • Charity Majors, Liz Fong-Jones, and George Miranda, Observability Engineering (debugging production with high-cardinality telemetry and tracing)
  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy, eds., Site Reliability Engineering (blameless postmortems and production debugging)