|
::Главная страница :: С++/Си :: Статьи |
Использование отладчика в Visual C++
В этой статье я очень кратко расскажу о возможностях встроенного отладчика Visual C++.
Запуск отладки
Чтобы запустить программу на отладку, нужно выбрать одну из команд меню Build->Start
Debug. Обратите внимание, что команда Attach to Process позволяет подключиться
к уже запущенному процессу.
Точки останова (Breakpoints)
Точки останова служат для прерывания программы, выполняемой в отладчике. Их
можно привязывать к конкретной строке в коде программы, к переменной или к сообщению
Windows. После того как программа прервана, её можно выполнять в пошаговом режиме
или просто проанализировать значения переменных, после чего продолжить выполнение.
Чтобы установить точку останова на строку вашей программы, достаточно выбрать команду Insert/Remove Breakpoint или нажать F9. Однако гораздо больше возможностей предоставляет окно Breakpoints из меню Edit. В нижней части этого окна находится список уже поставленных точек останова (любую из них можно активизировать, отключить или удалить), а вверху расположены три вкладки, предназначенные для установки точек останова различных типов.
Вкладка Location
Здесь устанавливаются точки останова, привязанные к конкретным строкам в вашей
программе. Адрес точки останова задаётся в поле Break at в виде {имя_функции,
имя_файла_cpp, имя_файла_exe} @номер_строки
Для формирования адреса можно воспользоваться окном Advanced breakpoint; чтобы вызвать это окно, щелкните на стрелке справа от поля ввода и выберите пункт Advanced. Обычно достаточно задать только номер строки и имя файла с исходным кодом.
В окне Condition можно дополнительно указать условие срабатывания точки останова. Условием может быть любое выражение. Если заданное вами выражение имеет тип bool, точка останова срабатывает, когда оно истинно; в противном случае она срабатывает при изменении значения выражения.
Бывают случаи, когда точку останова нужно пропустить несколько раз, прежде чем прерывать на ней программу. Специально для этого в окне Condition предусмотрено ещё одно поле Skip count (в самом низу). С помощью этого поля можно, к примеру, пропустить 10 итераций цикла и прервать программу только на одиннадцатой.
Вкладка Data
На этой вкладке устанавливаются точки останова по данным. Их отличие состоит
в том, что они могут сработать в любом месте программы, как только изменится
(или станет истинным) введённое вами выражение.
Если выражение имеет смысл только в определённом контексте (например, в нём используются локальные переменные какой-либо функции), этот контекст необходимо указать с помощью всё того же окна Advanced breakpoint, но здесь уже важно указать имя функции, а не файла.
Вкладка Messages
На этой вкладке устанавливаются точки останова на сообщения. В верхнем поле
указывается имя функции окна, а в нижнем – сообщение, приход которого в эту
функцию должен привести к прерыванию программы. Обратите внимание, что функция
окна должна иметь стандартный прототип:
LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
В программах, использующих MFC, удобнее ставить точки останова в соответствующие обработчики сообщений.
Пошаговая отладка
После того, как программа прервана, её можно выполнять в пошаговом режиме. Для
этого в отладчике предусмотрены следующие команды (из меню Debug).
Go (F5) – продолжить выполнение программы до следующей точки останова.
Step Into (F11) – выполнить одну инструкцию; если это вызов функции, точка выполнения
перемещается на первую инструкцию этой функции.
Step Over (F10) – выполнить одну инструкцию; если это вызов функции, то она
выполняется целиком.
Step Out (Shift+F11) – выполнять программу до возврата из текущей функции.
Run to Cursor (Ctrl+F10) – эквивалентна установке временной точки останова с
последующим вызовом команды Go.
Иногда в процессе отладки возникает необходимость перенести точку выполнения. Например, вы заметили ошибку и хотите "перескочить" через неё или, наоборот, хотите вернуться немного назад и выполнить фрагмент программы ещё раз. Чтобы это сделать, установите курсор в нужном месте и выберите команду Set Next Statement из контекстного меню (или нажмите Ctrl+Shift+F10).
В процессе пошаговой отладки программист может использовать целый ряд специальных окон отладчика для наблюдения за состоянием программы. Они описаны в последующих разделах.
Окно Variables
В этом окне автоматически отображаются значения локальных переменных (вкладка
Locals), переменных-членов класса, адресуемого указателем this (вкладка This),
а также всех переменных, которые используются в предыдущей и текущей строках
программы (вкладка Auto). На вкладке Auto также показываются возвращаемые значения
функций.
Чтобы изменить значение переменной в окне Variables, достаточно просто два раза кликнуть на старом значении и ввести новое.
Выпадающий список Context позволяет просматривать локальные переменные любой из вызванных в данный момент функций. Кроме того, код выбранной в нём функции отображается в окне редактора.
Вы, вероятно, заметили, что отладчик "умеет" распознавать стандартные структуры
данных (CString, RECT и т. п.) и показывать их содержимое в удобном виде. Оказывается,
можно не только изменить представление этих структур в окне Variables, но и
определить представление для собственных структур. Для этого нужно отредактировать
файл autoexp.dat, расположенный в каталоге
…\Common\MSDev98\Bin. Описание формата приводится в самом файле.
Окно Watch
Окно Watch позволяет просматривать значения переменных и выражений. Переменные
и выражения можно размещать на любой из четырёх вкладок. Добавить переменную
или выражение в окно Watch можно одним из следующих способов:
- Ввести с клавиатуры
- Перетащить из окна редактора или из окна Variables
- Добавить из окна Quick watch
Чтобы изменить значение переменной, достаточно два раза кликнуть на старом значении и ввести новое. Значение выражений изменять нельзя.
Чтобы узнать тип переменной или выражения, нужно щёлкнуть по ним правой кнопкой и выбрать Properties из всплывающего меню.
В окне Watch можно наблюдать любые регистры процессора и изменять их значения, хотя это удобнее делать в окне Registers. Можно также использовать регистры в выражениях.
Можно указать отладчику, в каком формате выводить значение переменной/выражения, используя флаги форматирования. Эти флаги добавляются к имени переменной или выражению через запятую. Большинство из них совпадает с символами форматирования функции printf: d – целое число со знаком, u – беззнаковое целое, f – число с плавающей точкой, c – символ, s – строка и т. д. Однако есть четыре флага, на которых я хочу остановиться подробнее.
Флаг wm превращает код сообщения в его название, например:
0x01,wm = WM_CREATE
Флаг wc позволяет «расшифровать» стиль окна, например:
0x6840000,wc = WS_OVERLAPPEDWINDOW WS_CLIPSIBLINGS WS_CLIPCHILDREN
Флаг hr переводит коды ошибок Win32 и значения HRESULT, возвращаемые функциями
COM, в удобочитаемый вид, например:
0x02,hr = 0x00000002 Системе не удается найти указанный файл.
Наконец, в Visual C++ есть числовой флаг, который позволяет просмотреть заданное
количество элементов массива, адресуемого указателем (по умолчанию показывается
всего один элемент). Допустим, мы выделили динамический массив из 10 целых чисел:
Int *pInt = new[10];
Чтобы просмотреть его содержимое в окне Watch, нужно ввести:
pInt,10
Псевдорегистр ERR
Как известно, получить расширенный код ошибки после вызова функций Win32 API
можно с помощью GetLastError. Однако расставлять по всей программе вызовы GetLastError
крайне неудобно. Поэтому в отладчике Visual C++ предусмотрен специальный псевдорегистр
ERR, который всегда содержит расширенный код ошибки. Особенно удобно наблюдать
значение этого регистра, использую уже знакомый нам флаг hr. Добавьте ERR,hr
в окно Watch, и информация об ошибках в вызовах функций API всегда будет у вас
перед глазами.
Другие окна отладчика
Окно Registers. Позволяет просматривать и изменять значения регистров процессора.
Окно Memory. Позволяет просматривать и изменять содержимое ячеек памяти.
Окно Call Stack. Показывает последовательность вызванных функций. Используя
контекстное меню, можно отобразить также типы и значения параметров этих функций.
К тексту любой функции можно переместиться, сделав двойной щелчок на её имени.
Обратите внимание, что точки останова можно ставить прямо в этом окне.
Окно Disassembly. Показывает текст отлаживаемой программы на языке ассемблера.
Иногда без помощи этого окна ошибку в программе найти не удаётся.
Диалоги
Диалоги отладчика предоставляют вам ряд дополнительных возможностей. Они вызываются
из меню Debug.
Quick Watch. Имеет возможности, аналогичные возможностям окна Watch, с той
разницей, что в нём можно просматривать только одну переменную за раз. Используется,
когда вам не хочется добавлять переменную в окно Watch.
Exceptions. Позволяет настроить реакцию отладчика на возникновение системных
и пользовательских исключений.
Threads. Показывает список активных потоков. Позволяет приостановить (suspend)
или продолжить (resume) поток, а также установить на него фокус.
Modules. Показывает список загруженных модулей. Для каждого модуля выводится
диапазон адресов и имя файла.
Edit and Continue
В заключение хотелось бы упомянуть о новой мощной возможности, которая появилась
в Visual C++ 6.0 - Edit and Continue. С её помощью вы можете вносить изменения
в код программы и перестраивать её, не прерывая сеанса отладки.
Для этого достаточно вызвать команду Apply code changes из меню Debug (или нажать Alt+F10), после того как вы подправили исходные тексты. Более того, Visual C++ может вызывать для вас эту команду автоматически. Это будет происходить, если в окне Tools->Options на вкладке Debug установить флаг Debug commands invoke Edit and Continue.
Тематические
ссылки
|
Ваша ссылка | Ваша ссылка |
Обмен кнопками, ведение статистики, реклама. |
|||