Какой из компонентов java предоставляет инструмент для отладки программы debugging tools
Написать код - пол дела. Нужно его ещё заставить работать правильно. В этом нам очень сильно помогают IDE и средства отладки.
На примере IntelliJ IDEA предлагаю познакомиться с тем, как мы можем узнать, что же происходит с нашим кодом, когда он работает. Debug тема обширная, поэтому данный обзор на глубокое погружение, словно дайвер, не предлагает. Но надеюсь снорклинг точно )
Вступление
- Среда разработки: Бесплатная IntelliJ Idea Community Edition
- Установленный Maven
- Сервер приложений WildFly 12.0.0.Final
- Исходный код официальных примеров: Quick Start Source Code
Далее нужно запустить выбранный нами проект на сервере. Этот процесс описан в небольшой документации, которую можно найти в самом проекте: \hibernate4\README.adoc Как и указано в этой документации, нам нужно в каталоге hibernate4 выполнить команду: mvn clean package wildfly:deploy Ожидаем, когда нам напишут, что сборка выполнена успешно:
Remote Debug
Итак, нам нужно настроить Debug режим, чтобы наша IDE управляла исполнение кода на сервере приложений. IntelliJ Idea поставляется в двух вариантах: бесплатный (Community) и платный (Ultimate). Последний можно официально попробовать в виде EAP. В Ultimate версии всё просто - сервер приложений можно запускать сразу из IDE в режиме дебага. А вот в Community версии надо немного действий сделать вручную. Поэтому, рассмотрим случай посложнее, т.е. настройка в Community версии. В Community версии есть некоторые ограничения. В частности, из неё нельзя запускать сервер приложений. Но можно настроить удалённую отладку (Remote Debug), когда где-то отдельно есть запущенный сервер с нужным нам приложением. Воспользуемся описанием настройки отсюда: Remote debug Wildfly in IntelliJ Idea community edition (настройка Remote Run Configuration для 8787 порта). После настройки запускаем в Debug режиме нашу новую конфигурацию:
Процесс Debug'а
Давайте «отдебажим» сохранение записи. Для этого надо сначала определиться с местом, где мы будем исследовать. Судя по окну, нам нужна кнопка «Register». Давайте найдём её в коде. Итак, нам нужен элемент, у него должен быть текст: "Register". Или она должна как-то относится к этому. Нажимаем Ctrl+Shift+F и ищеём Register в кавычках. Видим, что такая есть на index.xhtml.
Итак, мы видим, что при регистрации вызывается memberController.register Судя по всему, это должен быть некоторый java класс. Нажимаем Ctrl+N , ищем:
Действительно, такой класс есть . Переходим в него. Видимо, тут должен быть метод register. Нажимаем Ctrl+F12 и ищем метод register
Действительно, нашли. Судя по всему, регистрация происходит тут, в memberRegistration.register. Нажимаем Ctrl и кликаем по методу, чтобы «провалиться» в него:
Давайте теперь поставим «точку остановки» или Break Point. Это такой маркер, который говорит, где выполнение кода должно приостановиться. Мы в этот момент получим возможность узнать много интересного. Чтобы его поставить нужно кликнуть в место правее номера строки.
Отлично. Что мы можем ещё сделать? Мы можем открыть контекстное меню и выбрать там Evaluate Expression (или через меню Run -> Evaluate Expression). А ещё лучше на панели управления дебаггером:
Это супер замечательная возможность в точке останова, имея доступ ко всему, к чему есть доступ к этом месте кода, выполнить любой код, который можно было бы выполнить в этом месте. Например:
На панели управления дебаггером есть также кнопки управления, которые отвечают за то, куда необходимо переместить управление ходом выполнения программы. Не правда ли, магия?) Нажимая кнопку F8 (Step Out) мы ходим по коду без заходов в методы. Нажав F9 мы прекращаем ходить по строкам кода дебаггером, а отдаём дебаггером управление ходом выполнения программы. Если мы нажмём F7 (Step Into), то мы пойдём по коду с заходом в каждый метод, который встретим на своём пути. Кстати, обратите особое внимание на вот этот информационный блок:
Тут показан поток, в котором мы находимся и методы в стэке текущего потока. Но и это ещё не всё. Для удобства, можно открыть вкладку фрэймов. Для этого она должна быть включена:
Теперь на вкладке фрэймов мы видим информацию о переходе от метода к методу, т.к. начали ходить по коду при помощи Step Into.
Как мы видим, не всегда нас может перебросить туда, где сейчас выполнение программы. Мы сейчас находимся в «getDelegate:469, AbstractEntityManager (org.jboss.as.jpa.container)». Но на самом деле, мы в реализации. Об этом свидетельствует класс, указанный у this:
Смотрим на this. Как мы знаем, он указывается на текущий объект. Мы в TransactionScopedEntityManager. Почему же Idea нам не может показать код? Дело в том, что IntelliJ Idea сейчас не знает ни про какой TransactionScopedEntityManager, т.к. он не подключен к нашему проекту (его нет в зависимостях проекта). Когда работает сервер приложений, то внутри него крутится много-много всяких библиотек. А нам про них известно очень мало, т.к. в общем случае нам не нужно копаться во внутренностях, нам нужно чтобы оно просто работало. Но иногда этого требует работа или спортивный интерес. Тогда, надо об этой библиотеке сообщаить Idea, чтобы она знала, где брать код классов.
Подключение сторонних библиотек для дебага
Теперь же переходим к описанию зависимости. На этой страничке есть возможность скачать исходный код. Отлично, теперь код у нас скачан. Осталось подключить библиотеку. Подключается она предельно просто. Нам нужно открыть настройки проекта:
Там выбираем «Libraries» и в раздел «Sources» добавляем полученные исходные коды, а в разделе «Classes» указываем сам jar файл библиотеки из каталога WildFly, который нами был найден при помощи Far Manager’а. После этого мы увидим при переходе по F7 содержимое класса AbstractEntityManager и TransactionScopedEntityManager, а так же станет доступен через поиск по классам через Ctrl+N.
Break Points с условиями
Вернёмся теперь к Break Points. Иногда, мы хотим остановиться не всегда, а только при каком-нибудь условии. Что же делать? И тут нам тоже поможет наша IDE. Поставив Break Point мы можем назначит ей условие. Например, поставим точку и нажмём по ней правой кнопкой мыши:
Теперь точка остановки сработает только тогда, когда имя будет Maximilian. По кнопке More Вам будут доступны расширенный набор настроек для Break Point’ов.
Break Points на исключения
Иногда мы можем получать ошибку и хочется проследить, откуда она идёт. Тогда мы можем добавить точку остановки не на конкретную строку кода, а на место, где будет брошено исключение. Для этого нужно раскрыть список всех точек остановки:
HotSwap классов
Дебаггер — удивительная вещь. Она помимо дебага позволяет изменять классы! Да, ресурсы (такие как xhtml стриницы, например) не изменить так просто. Но вот код java классов можно подменить на лету (это и называется Hot Swap). Для этого достаточно при присоединённом дебаггере изменить класс и выполнить Run -> Reload Changed Classes. Полезный обзор на эту тему: 4 free ways to hot-swap code on the JVM
Некоторые ошибки трудно воспроизвести на вашем персональном компьютере, но их легко воспроизвести на производственных или тестовых машинах. Это обычная ситуация, с которой часто сталкиваются профессиональные Java-разработчики. Для отладки таких проблем OpenJDK предоставляет два инструмента: remote debugging и jdb . Эта статья посвящена jdb .
Для приложений Java типичными производственными и тестовыми машинами являются серверы Linux без графического интерфейса, поэтому доступны только инструменты командной строки. И мы не можем использовать профессиональные IDE, такие как IntelliJ IDEA, Eclipse или Apache NetBeans IDE.
В таких сценариях мы можем использовать jdb . jdb - это отладчик командной строки, входящий в состав OpenJDK.
Это перевод руководства для начинающих. Очевидно эксперты все это знают и им не стоит тратит время на его чтение.
Отладка Java с помощью утилиты "jdb"
jdb расположена в каталоге jdk/bin. Она использует интерфейс отладки Java (JDI) для запуска и подключения к целевой JVM. Интерфейс отладки Java (JDI) предоставляет интерфейс языка программирования Java для отладки приложений на языке программирования Java. JDI является частью архитектуры отладчика платформы Java (Java Platform Debugger Architecture).
В этом разделе мы рассмотрим, как подключить jdb к java-приложению и начать отладку и мониторинг.
Команда jdb
Формат команды jdb:
Пример Java приложения для отладки
Ниже приведен пример Java класса, который мы собираемся отладить и попытаться понять различные доступные функции. Важно скомпилировать этот класс с параметром «-g» (javac -g Test.java), который генерирует всю отладочную информацию, включая локальные переменные. По умолчанию генерируется только информация о номере строки и исходном файле.
Подключение jdb к java-приложению
Приведенная ниже команда - это наиболее распространенный способ запуска приложения с отладчиком jdb. Здесь мы не передаем никаких параметров jdb, мы передали только имя класса, который не требует никаких аргументов:
Таким образом, мы запускаем выполнение основного класса «Test» аналогично тому, как мы запускаем выполнение основного класс в среде IDE. jdb останавливает JVM перед выполнением первой инструкции этого класса.
Другой способ использовать команду jdb для подключения ее к уже запущенной JVM. Синтаксис для запуска JVM с портом отладчика:
Чтобы подключить jdb к этому удаленному jvm, используйте синтаксис ниже:
В этой статье мы не будем подробно рассматривать удаленную отладку.
Отладка и мониторинг
Ниже приводится команда для присоединения jdb к Java-программе Test:
Установите точку останова в строке 5, используя команду «stop», как показано ниже:
Запустите выполнение основного класса приложения с помощью команды "run":
Выполнить текущую строку с помощью команды «step»:
Выполнить текущую строку с помощью команды «step»:
Печать локальной переменной i с помощью команды "print":
Печать всех локальных переменных в текущем фрейме стека с использованием команды "locals":
Выгрузите стек потока, используя команду "where":
Выдать список потоков в запущенном приложении, используя команду "threads":
Продолжить выполнение с точки останова, используя команду cont :
Все доступные команды jdb можно получить используя команду "help":
Поддерживается весьма стандартный синтаксис команд.
Команды запуска могут быть помещены в файлы "jdb.ini" или ".jdbrc" в каталогах user.home или user.dir.
Заключение
Чтобы помочь вам, автор статьи написал электронную книгу 5 steps to Best Java Jobs. Вы можете загрузить это пошаговое руководство бесплатно!
В процессе отладки приложений работающих на JVM посредством дебаггера в Eclipse меня всегда впечатляло то, сколько доступа можно получить к данным приложения — потокам, значениям переменных и т.п. И в то же время периодически возникало желание «заскриптовать» некоторые действия или получить больше контроля над ними.
Например, иногда для того чтоб «мониторить» состояние какой-то переменной, меняющейся в цикле, я использовал условный брейкпойнт, условием к которому был код вроде «System.out.println(theVariable); return false». Этот хак позволял получить лог значений переменной практически не прерывая работы приложения (она, естественно, всё-таки прерывалась на время выполнения кода условия, но не более). Плюс, нередко при просмотре каких-нибудь данных через вид Display порядком раздражало то, что результат евалюейшна кода в Display введённого добавлялся тут же после него.
В общем хотелось получить возможность делать всё то же самое например через Bean Shell или Groovy Shell, что в принципе аналогично программному дебагу. По логике это не должно было быть сложно — ведь делает же это как-то сам Eclipse, верно?
Проведя некоторый рисёрч я смог получить доступ к отладочной информации JVM программно, и спешу поделится примером.
О JPDA и JDI
Для отладки JVM придуманы специальные стандарты, собранные вместе под «зонтичным» термином JPDA — Java Platform Debugger Architecture. В них входят JVMTI — нативный интерфейс для отладки приложений в JVM посредством вызова сишных функций, JDWP — протокол передачи данных между дебаггером и JVM, приложения в которой отлаживают и т.д.
Всё это выглядело не особо релевантно. Но сверх этого всего в JPDA входит некий JDI — Java Debug Interface. Это Java API для отладки JVM приложений — то, что доктор прописал. Официальная страница о JPDA подтвердила наличие reference имплементации JDI от Sun/Oracle. Значит, оставалось только начать ней пользоватся
Пример
В качестве proof of concept я решил попробовать запустить два Groovy Shell-а — один в отладочном режиме в качестве «подопытного», второй в качестве отладчика. В подопытном шелле была задана строчная переменная, значение которой требовалось получить из шелла-«отладчика».
Подопытный был запущен с следующими парметрами:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7896
Т.е. JVM была запущена в режиме удалённой отладки через TCP/IP, и ожидала соединения от отладчика на порту 7896.
Также в подопытном Groovy Shell была выполнена следующая команда:
Соответственно значение “Some special value” должно было быть получено в отладчике.
Т.к. это не просто значение поля какого-нибудь объекта, для того чтоб его получить надо было немного знать внутренности Groovy Shell (или как минимум подглядывать в исходники), но тем интереснее и реалистичнее мне показалась задача.
Далее дело было за «отладчиком»:
Рассмотрим всё пошагово:
Соединение с JVM
При помощи JDI соединяемся с JVM которую задумали отлаживать (хост == локалхост т.к. я всё делал на одной машине, но сработает аналогично и с удалённой; порт же тот, что был выставлен в debug-параметрах «подопытной» JVM).
JDI позволяет присоединятся к JVM как через сокеты, так и напрямую к локальному процессу. Поэтому VirtualMachineManager возвращает больше одного AttachingConnector-а. Мы выбираем нужный коннектор по имени транспорта («dt_socket»)
Получение стактрейса потока main
Полученный интерфейс к удалённой JVM позволяет посмотреть запущенные в ней потоки, приостановить их и т.п. Но для того, чтоб иметь возможность делать вызовы методов в удалённой JVM нам нужен поток в ней, который был бы остановлен именно брейкпойнтом. О чём собственно гласит следующий пункт JDI javadoc:
«Method invocation can occur only if the specified thread has been suspended by an event which occurred in that thread. Method invocation is not supported when the target VM has been suspended through VirtualMachine.suspend() or when the specified thread is suspended through ThreadReference.suspend().»
Для установки брейкпойнта я пошёл несколько специфическим путём — не заглядывать в сорцы Groovy Shell а просто посмотреть что сейчас происходит в JVM и выставить брейкпойнт прямо в том, что происходит.
В потоках подопытной JVM был обнаружен поток main, и в его стактрейс я и заглянул. Поток был предварительно остановлен — чтоб стактрейс оставался актуален во время последующих манипуляций.
В результате получил такое:
Установка брейкпойнта
Итак, мы имеем стактрейс остановленного потока main. API JDI возвращает для потоков так называемые StackFrame, из которых можно получить их Location. Собственно сей Location и требуется для установки брейкпойнта.
Не долго думая, локейшн я взял из «jline.ConsoleReader$readLine.call», и в него установил брейкпойнт, после чего запустил поток main работать дальше:
Теперь брейкпойнт установлен. Переключившись в подопытный Groovy Shell и нажав ввод я увидел что он действительно остановился. У нас есть остановка потока на брейкпойнте — всё готово к вмешательству в работу подопытной JVM.
Получение ссылки на объект Groovy Shell
API JDI позволяет из StackFrame получать видимые в них переменные. Чтоб получить значение переменной из контекста Groovy Shell надо было сначала вытянуть ссылку на сам шелл. Но где он?
Подсматриваем все видимые переменные во всех стек фреймах:
Обнаружился стек фрейм в объекте «org.codehaus.groovy.tools.shell.Main» с видимой переменной shell:
«48: org.codehaus.groovy.tools.shell.Main:131 in thread instance of java.lang.Thread(name='main', искомого значения из Groovy Shell
У shell.Main имеется поле interpreter. Зная немного внутренности Groovy Shell я заранее знал что переменные GroovyShell контекста хранятся в объекте типа groovy.lang.Binding, который можно получить вызвав getContext() у Interpreter (вызов метода необходим т.к. соответствующего поля со ссылкой на groovy.lang.Binding в Interpreter нет).
Из Binding значение переменной можно получить вызовом метода getVariable(String varName).
Последняя строка скрипта вернула нам ожидаемое значение «Some special value» — всё работает!
Последний штрих
Шутки ради я решил еще и поменять значение этой переменной из отладчика — для этого достаточно было вызвать у Binding метод setVariable(String varName, Object varValue). Что может быть проще?
Чтоб убедится что всё сработало я также задизейблил брейкпойнт и запустил обратно приостановленный ранее по брейкпойнту поток main.
Переключившись в последний раз в подопытный Groovy Shell я проверил значиение переменной myVar, и оно оказалось равно «Surprise!».
Выводы
Быть Java программистом это счастье, ибо Sun подарил нам мощные инструменты — а значит большие возможности (-:
А если еще дописать к Groovy удобные врапперы (метаклассы) для JDI можно сделать программную отладку из Groovy Shell вполне приятной. К сожалению пока-что она выглядит где-то так же, как, например, доступ к полям и методам через reflection API.
Все мы, разработчики, знакомы с отладчиками и используем их ежедневно - они важная часть процесса программирования.
Но давайте будем честными. Обычно мы используем только опцию точки останова. При большом желании мы можем использовать условную точку останова.
Но знаете что, отладчик IntelliJ IDEA имеет множество мощных и передовых функций, которые полезны для более эффективной и простой отладки.
Чтобы помочь вам, мы составили список советов и приемов от наших разработчиков в Lightrun. Мы надеемся, что эти советы помогут вам быстрее находить и устранять ошибки.
1. Используйте точки останова по исключениям
Точки останова - это места в коде, которые позволяют остановить программу и включить отладку. Они позволяют изучить поведение кода и его функции, чтобы попытаться определить ошибку.
Мы рекомендуем использовать точку останова по исключениям. Этот тип точки останова приостанавливает выполнение программы в соответствии с типом исключения, а не в заранее определенном месте. Мы особенно рекомендуем точку останова IntelliJ Exception, потому что вы также можете фильтровать класс или пакет, частью которого являются исключения.
Таким образом, вы можете определить точку останова, которая остановится на строке, генерирующей исключение NullPointerException и игнорирует исключения, генерируемые из файлов, принадлежащих другим библиотекам.
Для этого вам нужно определить пакет, в котором находятся файлы вашего проекта. Это поможет вам сфокусировать анализ поведения вашего кода.
Lightrun предлагает моментальные снимки - точки останова, которые не останавливают работу программы. Узнайте больше здесь.
2. Используйте условия в ваших точках останова
Это один из самых малоиспользуемых инструментов в отладчиках и, возможно, один из самых эффективных. Используйте условия, чтобы сузить круг проблем гораздо проще и сэкономить время и усилия по поиску проблем. Например, в цикле вы можете определить точку останова, которая остановится только при фактической ошибке, избавляя вас от ручного обхода циклов, пока вы не столкнетесь с проблемой!
В приведенном ниже цикле вы можете видеть, что точка останова остановит сервис, когда значение идентификатора агента равно нулю. Таким образом, вместо того, чтобы генерировать исключение с null указателем, мы сможем проверить текущее состояние VM (виртуальной машины) до того, как это произойдет.
Обратите внимание, что условие может быть очень сложным и даже вызывать методы как часть условия.
Lightrun предлагает условия для всех действий: снимки, логи и т. д. Подробнее читайте здесь.
3. Включите меню «Internal Actions» для разработки собственных плагинов.
Если вы пишете собственный плагин IntelliJ IDEA, включите внутренние действия (Tools -> Internal Actions) для упрощения отладки. Эта функция включает в себя множество удобных опций, таких как инспектор компонентов и отладчик пользовательского интерфейса. Всегда удобно иметь в своем распоряжении широкий набор инструментов, предоставляющих вам возможности, о которых вы, возможно, никогда не думали.
Чтобы включить внутренние действия, выберите «Help -> Edit Custom Properties». Затем введите idea.is.internal=true и сохраните. После перезапуска вы должны увидеть новую опцию в меню «Tools».
4. Используйте функцию «Analyze Thread Dump».
Дамп потока - это моментальный снимок, который показывает, что каждый поток делает в определенное время. Дампы потоков используются для диагностики системы и проблем с производительностью. Анализ дампов потоков позволит вам выявить тупиковые ситуации или проблемы конкуренции.
Мы рекомендуем использовать функцию IntelliJ «Analyze Thread Dump» из-за ее удобных возможностей просмотра, которые упрощают анализ дампа. «Analyze Thread Dump» автоматически обнаруживает трассировку стека в буфере обмена и мгновенно помещает ее со ссылками на исходный код. Эта возможность очень полезна при просмотре дампов стека из журналов сервера, потому что вы можете мгновенно перейти к соответствующим файлам, как при локальной трассировке стека.
Чтобы получить доступ к функции, перейдите в меню «Analyze». IDE поддерживает активацию этой функции динамически, когда IDE обнаруживает трассировку стека в буфере обмена.
5. Используйте отладчик потока.
Потоки Java 8 очень удобны в использовании, но, как известно, их сложно отлаживать. Потоки объединяют несколько функций в один оператор, поэтому простое переключение операторов с помощью отладчика нецелесообразно. Вместо этого вам понадобится инструмент, который поможет вам проанализировать, что происходит внутри потока.
В IntelliJ появился новый классный инструмент - Stream Debugger. Вы можете использовать его для визуальной проверки результатов потоковой операции. При достижении точки останова в потоке нажмите значок отладчика потока в отладчике. Вы увидите отображение пользовательского интерфейса значения элементов потока на каждом этапе/функции потока. Таким образом, визуализируется каждый шаг, и вы можете видеть операции в потоке и обнаруживать проблему.
6. Используйте точку наблюдения за полем (Field Watchpoints)
Точка наблюдения за полем - это точка останова, приостанавливающая выполнение программы при доступе к заданному полю или его изменении.
Она может быть очень полезно, когда вы исследуете и обнаруживаете, что поле имеет неправильное значение, и вы не знаете, почему. Наблюдение за этим полем может помочь определить причину неисправности.
Чтобы установить эту точку останова, просто добавьте ее в строку нужного поля. Программа будет приостановлена, когда, например, будет изменено поле:
7. Отладка микросервисов с помощью подключаемого модуля Lightrun.
Плагин Lightrun IntelliJ позволяет добавлять журналы, снимки состояния и показатели производительности во время работы сервиса. Это означает, что вы можете добавлять инструменты в производственную и промежуточную среды. Вы можете отлаживать монолитные микросервисы, Kubernetes, K8, Docker Swarm, ECS, Big Data Workers, бессерверную систему и многое другое. Поддержка нескольких экземпляров доступна через механизм тегов.
Плагин Lightrun полезен для экономии времени, поэтому вместо многократных итераций локального воспроизведения сред, перезапусков и повторных развертываний вы можете выполнять отладку прямо в производственной среде.
8. Используйте друга - реального или воображаемого.
Когда дело доходит до мозгового штурма, 1 + 1 = 3. А когда дело доходит до решения сложных проблем отладки, вам понадобятся все умственные способности, которые вы можете использовать.
Работа с кем-то позволяет по-новому взглянуть на проблему по-другому и может выявить детали, которые вы упустили.
Или вы оба дополняете друг друга, пока не достигнете решения. Просто задавая друг другу вопросы и опровергая некоторые предположения друг друга, вы придете к новым выводам, которые помогут вам найти проблемы.
Вы также можете использовать друг друга для «Rubber Duck Debugging», или, как мы любим это называть, «Cheetah debugging».
Мы надеемся, что эти советы наших разработчиков помогут вам в отладке. Не стесняйтесь делиться с нами своими советами по отладке и передовыми методами, а также делиться этой записью в блоге, чтобы помочь другим.
Вы можете найти список онлайн сообществ разработчиков Java здесь.
Как мы уже упоминали в подсказке № 7, плагин Lightrun IntelliJ позволяет разработчикам отлаживать живые микросервисы, не прерывая их. Вы можете безопасно добавлять журналы и показатели производительности в производственную и промежуточную среду в режиме реального времени по запросу. Запросите демонстрацию и узнайте больше.
У программистов есть свой сленг, хотя многие считают, что это технический жаргон. В любом случае, вам не избежать ни знакомства с ним, ни детального изучения. Так что начинайте втягиваться.
Одним из первых слов, с которым вы познакомитесь, будет слово баг , от английского bug (жук). Это слово обозначает ошибку в программе, когда программа делает что-то не то или не так. Или просто странно работает.
Однако, если программист считает, что программа, хоть и работает странно, но он именно так он и задумывал, обычно заявляет что-то типа «это не баг, это фича». Что породило кучу интернет-мемов.
История слова bug
Самой распространённой версией происхождения слова баг является такая легенда.
В сентябре 1945 года ученые Гарвардского Университета тестировали один из первых компьютеров — Mark II. Компьютер не работал, и в процессе проверки всех плат они нашли мотылька, застрявшего между контактами электромеханического реле.
Извлеченное насекомое было вклеено скотчем в технический дневник и сопровождено надписью, мол «баг найден и устранен».
Считается, что именно эта смешная история и послужила началом использования слова баг как обозначения ошибки, а слово дебаг (debug) стало синонимом устранения ошибок.
2. Отладка программы
Для устранения багов в своих программах программисты используют специальные программы-отладчики ( debugger ). Некоторые из этих программ умеют отлаживать даже машинный код.
Java-программисты для отладки ( debugging ) своих программ используют IDE. Такие как Intellij IDEA, Eclipse и Net Beans. IntelliJ IDEA на сегодняшний день является самой мощной IDE, поэтому мы рассмотрим процесс отладки на ее примере.
Intellij IDEA может запустить вашу программу в двух режимах:
Режимы запуска программы | Иконка на панели | Горячие клавиши |
---|---|---|
Обычное выполнение | | Shift + F10 |
Запуск в режиме отладки | Shift + F9 |
С обычным режимом работы вы уже знакомы: программа запустится, отработает и завершится. А вот режим отладки несет для вас немало сюрпризов.
Режим отладки
Режим отладки позволяет пошагово выполнить всю вашу программу. Или правильнее будет сказать, построчно : строка за строкой . При этом вы можете наблюдать значения переменных на каждом шаге программы (после выполнения каждой строки кода). И даже менять их значения!
Чтобы минимально овладеть искусством отладки программы, вам нужно изучить три вещи:
- Точки остановки
- Пошаговое выполнение
- Просмотр значений переменных
3. Точки остановки ( Break Points )
IDE позволяет вам разместить в коде специальные метки — точки остановки ( break point ). Каждый раз, когда программа, запущенная в режиме отладки, будет доходить до строки, отмеченной как break point , она будет становиться на паузу.
Чтобы поставить break point на определенной строке, нужно просто кликнуть в IDEA слева от этой строки. Пример:
В результате строка будет отмечена точкой остановки (break point), и Intellij IDEA подсветит ее красным цветом:
Повторный клик мышкой на панели слева от кода снимет установленную break point .
Также break point можно просто поставить на текущей строке с помощью горячей комбинации клавиш — Ctrl + F8 . Повторное нажатие Ctrl + F8 на строке, где уже есть break point , удаляет ее.
4. Запуск программы в режиме отладки (дебага)
Если у вас в программе есть хотя бы одна точка остановки, вы можете запускать программу в режиме отладки ( Shift + F9 или «иконка с жуком»).
После запуска в режиме отладки программа выполняется как обычно. Но как только она дойдет до выполнения строки кода, помеченного break point , встанет на паузу. Пример:
В верхней половине скриншота вы видите код программы с двумя точками остановки. Программа замерла на строке 5 — отмечена синей линией. Строка 5 еще не выполнилась: в консоль еще ничего не выводилось.
В нижней половине экрана вы видите панели режима отладки: панель Debugger , панель Console (вывод на экран), а также набор кнопок для режима отладки.
Вы можете снять вашу программу с паузы (продолжить ее выполнение), если нажмете кнопку Resume Program на панели слева снизу (или нажмете клавишу F9 ).
Если нажать такую кнопку (или F9 ), программа продолжит работу, пока не встретит следующую точку остановки или не завершится. Вот что мы увидим после нажатия такой кнопки:
Программа остановилась на второй точке остановки, а в консоль выведены слова Привет и И – признак того, что из трех строк вывода на экран выполнились только две.
5. Пошаговое выполнение
Если ваша программа работает в режиме отладки, вы также можете выполнять ее пошагово: один шаг — одна строчка . Для пошагового выполнения есть две горячие клавиши: F7 и F8 : каждая из них приводит к выполнению текущей строки кода. Но сначала вам нужно будет все же остановить вашу программу с помощью break point .
Если вы хотите выполнять вашу программу построчно, вам нужно поставить break point в самом начале метода main() и запустить ее в режиме отладки.
Когда программа остановится, вы сможете начать построчное ее выполнение. Одно нажатие клавиши F8 – одна строка.
Вот как будет выглядеть наша программа после остановки и нажатия клавиши F8 один раз:
Первая строка метода main уже выполнилась, и текущая строка — вторая. Вы также можете видеть в нижней части скриншота, что на экран уже вывелось слово Привет .
6. Пошаговое выполнение с заходом в методы
Если у вас есть в программе собственные методы, и вы хотите, чтобы в режиме отладки ваша программа не просто выполнялась пошагово, но и заходила внутрь ваших методов, для «захода в метод» вам нужно нажимать не клавишу F8 , а клавишу F7 .
Допустим, вы пошагово выполняете программу и сейчас остановились на 4-й строке. Если вы нажмете кнопку F8 , IDEA просто выполнит четвертую строку и перейдет к пятой.
А вот если вы нажмете F7 , IDEA будет пошагово выполнять метод main2() :
Все очень просто. Если вам не сильно важно, что и как происходит внутри метода, вы нажимаете F8 , если важно — F7 и пошагово выполняете весь его код.
Читайте также: