Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
17 матлаб.docx
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
93.6 Кб
Скачать

Завершение отладки

Сеанс отладки автоматически заканчивается, когда завершается отлаживаемая программа. Кроме этого, отладку можно прекратить в любой момент, вызвав команду Stop Debugging из меню Debug или нажав Shift+F5.

ПРИМЕЧАНИЕ

Здесь и далее для команд отладчика приводятся клавиатурные сокращения, выбранные в Visual C++ по умолчанию. При желании их можно изменить на любые другие.

Точки останова

Как я уже говорил, точки останова играют важную роль в процессе отладки приложения. Visual C++ поддерживает множество разновидностей точек останова. Условием для прерывания программы может быть достижение некоторой команды, изменение глобальной переменной, приход заданного сообщения Windows и т. п. Приостановленную программу можно выполнять в пошаговом режиме, анализировать текущие значения переменных и даже вносить в программу изменения прямо "на лету", не прерывая сеанса отладки.

Окно Edit->Breakpoints

Окно Breakpoints из меню Edit предоставляет дополнительные возможности для работы с точками останова. В нижней части этого окна находится список уже поставленных точек останова (любую из них можно активизировать, отключить или удалить), а вверху расположены три закладки, предназначенные для установки точек останова различных типов.

Закладка Location

Рисунок 5. Закладка Location

На закладке Location (рис. 5) настраиваются позиционные точки останова. Все рассмотренные выше разновидности точек можно установить и с этой закладки. Местонахождение точки останова указывается в поле Break at в формате:

{имя_функции, имя_исходного_файла, имя_двоичного_модуля} адрес

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

Для задания местонахождения точки останова можно воспользоваться окном Advanced breakpoint. Чтобы вызвать это окно, щелкните на стрелке справа от поля ввода и выберите пункт Advanced.

В окне Condition можно дополнительно указать условие срабатывания точки останова. Условием может быть любое выражение. Если выражение имеет тип bool, точка останова срабатывает, когда оно истинно; в противном случае она срабатывает при изменении значения выражения.

Бывают случаи, когда точку останова нужно пропустить несколько раз, прежде чем прерывать на ней программу. Специально для этого в окне Condition предусмотрено ещё одно поле, Skip count (в самом низу). С помощью этого поля можно, к примеру, пропустить 10 итераций цикла и прервать программу только на одиннадцатой.

Закладка Data

Рисунок 6. Закладка Data

На закладке Data (рис. 6) устанавливаются точки останова по данным. Их отличие состоит в том, что они могут сработать в любом месте программы, как только изменится (или станет истинным) введённое вами выражение.

Если выражение имеет смысл только в определённом контексте (например, в нём используются локальные переменные какой-либо функции), этот контекст необходимо указать в том же формате, что и для позиционной точки останова. Но здесь уже нужно указать имя функции, а не файла.

Visual C++ позволяет вам контролировать изменение не только отдельных переменных, но и массивов. Рассмотрим следующий фрагмент программы.

int main(int argc, char* argv[])

{

...

int array[10];

for(int i=0; i<10; i++)

array[i] = 0;

...

}

Если теперь задать на закладке Data точку останова в виде '{main,,} array', то программа будет прерываться каждый раз, когда хоть один элемент массива array меняет своё значение (в нашем примере – на каждой итерации цикла).

Можно также контролировать не целый массив, а только некоторую его часть. Для этого на закладке Data имеется поле ввода Enter the number of elements to watch in an array or structure. В этом поле задаётся количество элементов массива, которое нужно контролировать. Отсчёт ведётся от элемента массива, к которому вы обращаетесь в выражении (по индексу или указателю).

Вернёмся к нашему примеру. Чтобы отслеживать изменения в первых трёх элементах массива array, нужно задать для точки останова выражение '{main,,} array[0]' или '{main,,} *array'. Чтобы реагировать на изменения в элементах с третьего по пятый, нужно задать '{main,,} array[2]' или '{main,,} *(array+2)'. И в том, и в другом случае нужно задать количество контролируемых элементов - три.

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

Точки останова по данным являются мощнейшим отладочным средством. К сожалению, они не всегда работают надёжно. Так, Visual C++ не может отследить изменение переменной-члена класса, если объект этого класса адресуется указателем. Рассмотрим небольшой пример.

/* 01 */ class A

/* 02 */ {

/* 03 */ public:

/* 04 */ int m_i;

/* 05 */ };

/* 06 */

/* 07 */ int main(int argc, char* argv[])

/* 08 */ {

/* 09 */ A *pa = new A();

/* 10 */ pa->m_i = 1;

/* 11 */ delete pa;

/* 12 */ return 0;

/* 13 */ }

Допустим, нам требуется перехватить изменение переменной pa->m_i в 10 строке программы. Можно предположить, что для этого достаточно установить точку останова по данным на выражение {main,,}pa->m_i. Но, как показывает практика, эта точка никогда не сработает. Чтобы решить подобную проблему, можно прибегнуть к следующему трюку. Сначала нужно поместить переменную в окно Watch (например, перетащив ее мышью) в момент, когда программа прервана внутри функции, где данная переменная доступна. Далее нужно поставить перед именем переменной (в окне Watch) амперсанд, чтобы получить её адрес. Теперь нужно добавить точку останова по данным, указав полученный адрес вместо имени переменной на закладке Data. Чтобы определить необходимый размер контролируемой области памяти, нужно заставить Visual C++ интерпретировать этот адрес как указатель на определенный тип. Следует учесть, что установленная таким образом точка прерывания будет действовать корректно только в течение текущего сеанса отладки. В следующем сеансе отладки такую точку останова придется переустанавливать. Несмотря на сложность и неудобство данного способа, не стоит сбрасывать его со счетов, так как он позволяет находить очень сложные ошибки, например, проходы по памяти.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]