Отладка: 10 подходов к поиску багов в коде

0
1608
views

Перевод статьи «Debugging — you’re doing it wrong. 10 techniques to find a bug in your code».

Отладка: поиск багов в коде

Помните эти долгие, долгие часы, проведенные за отладкой? Когда вы всматриваетесь в код и не можете понять, что именно не в порядке? Вы не одиноки! Думаю, время от времени трудности с отладкой переживают все разработчики. В этой статье я расскажу вам о своих любимых подходах к поиску багов в коде.

Поискать информацию по сообщению об ошибке в Google

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

В большинстве случаев сообщение, с которым вы столкнулись, наверняка гуглил и кто-нибудь еще. Кроме того, у нас есть много таких прекрасных мест как StackOverflow и GitHub issues, где люди помогают друг другу. Благодаря этому вы можете найти не только ответ, но и советы о том, что нужно предпринять, чтобы подобная ошибка не возникала в дальнейшем. Так почему же не гуглить ошибки? Это самый простой способ из всех!

Console log

Я полагаю, это один из самых популярных способов поиска багов в кодовой базе. Мы добавляем предложения console.log(…) в код, заново запускаем приложение и пытаемся разобраться, что идет не так.

Я люблю этот способ и, как мне кажется, это подходящий вариант для поиска простых проблем, уже локализованных в нескольких классах. Но если вы вообще не представляете, что происходит и где притаился баг, начинать поиски при помощи console.log(…) будет плохой идеей. Потому что в этом случае можно пропустить что-то важное, что не попало в логи, и тогда вам придется многократно добавлять console log и перезапускать приложение, пока вы не найдете причину отказа.

Использовать отладчик

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

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

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

Отладка программы

Локализация проблемы

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

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

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

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

Создать несколько тестов

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

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

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

Анализ логов

Да, я знаю, что вы терпеть не можете анализировать все эти 10mb текстовых файлов с логами. Но довольно часто это позволяет сэкономить целые часы на отладке. Конечно, прежде всего следует адекватно настроить ведение логов. Файлы с логами должны собираться и храниться какое-то разумное количество времени. Но если соблюдены все условия – вам повезло. Это как использование console log, только у вас уже есть все console.log-и на своих местах, так что вы можете просто читать, какие действия выполняла система.

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

Отладка

Спросить у друга

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

Но. Прежде, чем спрашивать у кого-то, сначала необходимо просмотреть все доступные ресурсы самостоятельно. Если будете спрашивать у людей какую-то легкотню, написанную на второй странице документации, – будьте готовы спасаться бегством!

Git bisect

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

В этом случае git bisect вам поможет. Идея тут довольно простая. Вы начинаете процесс отладки (git bisect start), затем нужно пометить текущую версию как плохую, потому что здесь у нас баг (git bisect bad). После этого нужно сообщить git, какую версию считать хорошей – git bisect good 2.0.15. На этой стадии настройка завершена и мы можем начинать поиск.

git bisect выбирает коммит на середине отрезка bad-good и осуществляет проверку. Нам нужно проверить, есть ли баг в этой версии. Если да – запускаем git bisect bad, если нет – git bisect good. Затем git выбирает новый коммит на оригинальном отрезке bad-good и мы повторяем процесс, пока не найдем коммит с багом.

git bisect это очень мощный инструмент, поэтому полностью описывать его здесь мы не будем. Если вам интересно, хорошее пояснение есть здесь.

Поговорить с уточкой

Расскажите все резиновой уточке

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

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

Танцы с бубном

Это мой любимый способ решения проблем с программами. Все, что вам нужно, это бубен. Танцуйте вокруг своего рабочего стола, ударяя в бубен. Большой плюс, если на бубне нанесен логотип технологии, с которой вы работаете. Например, у меня есть бубен для решения проблем с микросервисами:

Танцы с бубном

Правда, для фронтенд-приложений он совершенно бесполезен.

Заключение

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

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