16 января 2010 в 18:21
Работа в IDE Visual C++ Express Edition 2008.
Сегодня рассмотрим некоторые приёмы работы с отладчиком и поучимся исправлять ошибки.
Приступим. Для сегодняшнего выпуска я создал новое решение solution. Оно включает в себя два проекта: hello_world и debugger (отладчик). В hello_world содержится код программы из первых выпусков, а вот с проектом debugger мы и будем работать.
В проект был добавлен один файл debugger.cc, который содержит следующий код:
#include <conio.h> #include <iostream> #include <clocale> using namespace std; int main () { setlocale(LC_CTYPE,"Russian"); char var = 'я'; cout << var; _getch(); return 0; }
Стартовым проектом по умолчанию выбран debugger.
В программе переменной var присваивается символ, а затем эта переменная выводится на экран.
Выбираем пункт меню Build → Build solution (Построение → Построить решение) или нажимаем F7. Смотрим на окно Output (Вывод) внизу экрана.
1>------ Build started: Project: hello_world, Configuration: Debug Win32 ------
2>------ Build started: Project: debugger, Configuration: Debug Win32 ------
1>Compiling...
2>Compiling...
2>debugger.cc
1>hello_world.cc
1>Compiling manifest to resources...
2>Compiling manifest to resources...
2>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
2>Copyright (C) Microsoft Corporation. All rights reserved.
1>Linking...
2>Linking...
1>Embedding manifest...
2>Embedding manifest...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://d:\job\c\solution\hello_world\Debug\BuildLog.htm"
1>hello_world - 0 error(s), 0 warning(s)
2>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
2>Copyright (C) Microsoft Corporation. All rights reserved.
2>Build log was saved at "file://d:\job\c\solution\debugger\Debug\BuildLog.htm"
2>debugger - 0 error(s), 0 warning(s)
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Здесь описан процесс сборки решения (building - сборка, построение). Сборка включает в себя компиляцию (compiling) и компоновку (linking). Кроме компиляции и сборки исходного кода в данном окне можно увидеть компиляцию и встраивание манифестных файлов (строки: Compiling manifest to resources... и Embedding manifest). На данный момент манифестные файлы нам не нужны. К концу данного текста встречаются две строки:
1>hello_world - 0 error(s), 0 warning(s)
2>debugger - 0 error(s), 0 warning(s)
Или:
1>hello_world - 0 ошибок, 0 предупреждений
2>debugger - 0 ошибок, 0 предупреждений
Эти строки говорят как была произведена сборка проектов. Если есть хоть одна ошибка, то собрать проект не получилось, соответственно его не получится и запустить. Если есть предупреждения, то проект запустить можно, но в коде что-то не так. Например, предупреждения выдаются когда переменные объявляются, но не используются.
И последняя строка относится к решению:
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Первое число - сколько проектов успешно (succeeded) собрано, второе - сколько собрать не получилось (failed). В данном случае успешно собраны оба проекта.
Сейчас сделаем несколько ошибок.
Для начала уберём из следующей строки точку с запятой:
char var = 'я'
Пытаемся скомпилировать проект. В окне вывода можно обнаружить следующие строки:
1>debugger - 1 error(s), 0 warning(s)
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
Первая строка означает, что в проекте debugger одна ошибка, а вторая - что один проект скомпилировался успешно, а сборка ещё одного завершилась неудачей.
В панели иструментов окна Вывод (output) есть три кнопки: Find Message in Code (Найти сообщение в коде), Go to Previous Message (Перейти к предыдущему сообщений) и Go to Next message (Перейти к следущему сообщению).
Чтобы найти ошибку, нужно щёлкнуть по одной из кнопок: Перейти к предыдущему сообщению или Перейти к следующему сообщению. В окне Вывод выделится строка в которой содержится сообщение об ошибке:
2>d:\job\c\solution\debugger\debugger.cc(14) : error C2146:
syntax error : missing ';' before identifier 'cout'
Сообщение значит примерно следущее: В файле debugger.cc в четырнадцатой строке (число в скобках) допущена ошибка C2146 и дано её описание - ошибка в синтаксисе: отсутствует ';' перед идентификатором 'cout'.
Теперь нужно щёлкнуть на кнопку Найти сообщение в коде. В редакторе выделится строка, где по мнению компилятора была допущена ошибка. Думаю, понятно что нужно сделать - добавить ';'.
Ошибки показываются прямо в окне Output. Но есть ещё одно специальное средство. Если во вкладках под окном Вывод нет вкладки Error List (Список ошибок), то выберите пункт меню View -> Other windows -> Error List (Вид -> Другие окна -> Список ошибок).
Теперь исправляем ошибку с точкой запятой и делаем новую. В слове char убираем букву r. И снова собираем решение.
В этот раз в окне Вывод, в проекте debugger появилось сообщение сразу о четырёх ошибках:
2>debugger - 4 error(s), 0 warning(s)
Можно просмотреть эти ошибки в окне Вывод, а можно и в окне Список ошибок. Для этого нужно открыть вкладку Error List:
В данном окне можно по выбору просматривать ошибки, предупреждения и сообщения.
Итак, здесь мы видим четыре ошибки. В окне Список ошибок несколько полей: тип, представленный значком (ошибка, сообщение или предупреждение), номер, описание, файл, строка.
Ошибки нужно всегда исправлять с самой первой.
В описании первой ошибки мы видим:
'cha': undeclared identifier
То есть необъявленный идентификатор cha. В общем-то уже понятно в чём проблема. Щёлкаем два раза на эту строку и курсор в редакторе перейдёт на нужную строку. Осталось только добавить букву r.
В некоторых случаях при сборке программы компилятор может выдать десятки ошибок, при этом реальных ошибок окажется 2-3.
Это что касается ошибок во время компиляции. Тут всё относительно просто.
Существуют также ошибки времени выполнения программы, которые в свою очередь делятся на две группы: логические ошибки, при этом программа выполняется нормально, но результат неверен (в одном из уроков раздела DirectX у нас будет замечательное упражнение на эту тему). Например: неверные значения переменных. Вторая группа ошибок времени выполнения приводит к остановке программы. Причина таких ошибок - работа с низкоуровневыми возможностями языка: выделение памяти (указатели), работа с файлами. Это разграничение конечно же довольно условно.
Для обработки ошибок из второй группы существует механизм исключений. С исключениями мы познакомимся позже. Здесь же мы рассмотрим возможности отладчика, которые сделают вашу жизнь намного легче.
В программе debugger я объявил одну переменную глобальной:
int i = 1;
А в код main добавил следущее:
float f1 = 1.5; float f2 = 2.5; float* ptr = &f2; ptr = &f1; cout << f1 << "\n";
Break points - точки прерывания (точки остановки)
Break points позволяют остановить выполнение программы в определённом месте. Для создания точки нужно всего-лишь щёлкнуть мышкой напротив нужной строки:
Собираем программу, жмём F5 или выбираем пункт меню Debug -> Start Debugging (Отладка -> Начать отладку).
На картинке показана уже запущенная программа с двумя точками прерывания. Во время отладки вместо окна Вывод появляются два новых.
В первом окне есть следующие вкладки: Autos (Автоматические данные), Locals (Локальные данные), Threads (Потоки), Modules (Модули), Watch 1 (Наблюдаемые данные 1).
Во втором окне: Call Stack (Стек вызовов), Breakpoints (Точки остановки), Output (Вывод).
Чтобы продолжить выполнение программы после точки прерывания нужно нажать F5. Чтобы закончить отладку - Shift+F5.
Чтобы добавить к интерфейсу отладки дополнительные окна, необходимо выбрать пункт меню Debug → Windows -> Необходимое окно (Отладка -> Окна -> Необходимое окно).
На данный момент нам интересны вкладки Locals (Локальные данные) и Watch 1.
На вкладке Locals видны все локальные переменные. Здесь можно узнать имя переменной, значение и тип.
Если переменных в программе слишком много, то часть из них можно добавить в наблюдаемые. Для этого во время отладки, в редакторе щёлкните на имя переменной правой кнопкой мыши и выберите пункт Add Watch (Добавить в наблюдаемые):
После этого, данные о переменной можно увидеть на вкладке Watch 1.
Обратите внимание, что нельзя поставить точку остановки в глобальной области видимости, только в функции main() и на уровнях ниже.
Ну и напоследок несколько слов об остальных вкладках:
* На вкладке Autos можно найти значения переменный, которые используются непосредсвенно рядом с текущей точкой остановки.
* На вкладке Threads (Потоки) перечислены все потоки программы. Очень долго мы будем работать с однопоточнымии приложениями, так что пока эта вкладка для нас не актуальна.
* Modules. Здесь перечислены модули (файлы) необходимые для запуска программы.
* Call stack (стек вызовов) позволяет посмотреть вызовы функций программы. Кстати, загляните в эту вкладку - узнаете как запускается программа.
* Output (вывод). На данной вкладке можно узнать в каком порядке загружаются модули необходимые для выполнения программы.
Вот в общем-то все средства необходимые для более-менее комфортного существования в страшном мире отлова ошибок. Конечно же не рассмотрены более продвинутые средства. Например, фильтры точек остановки, просмотр регистров или кода ассемблера. Но это, наверное, тема другого сайта.
На сегодня всё. В качестве упражнений позапускайте старые программы и проследите значения: объектов, указателей, массивов.
комментарии отсутствуют
авторизуйтесь