Средства отладки программ
Структурной называется ошибка, не позволяющая программе выполнить оператор (команду), наименование которого записано без ошибки. Синтаксической называется ошибка, не позволяющая Visual FoxPro «понять» команду (обычно это описка в синтаксисе команды). Логической называется ошибка, из-за которой при отсутствии структурных и синтаксических ошибок Visual FoxPro программа не обеспечивает получение нужного результата. Причиной логических ошибок является неверный алгоритм.
Диагностика логических ошибок работа трудоемкая и средствами Visual FoxPro практически не обеспечивается. Единственным надежным средством обнаружения и устранения логических ошибок является расчет контрольных примеров и проверка соответствия счета по программе контрольному счету.
Примеры структурных ошибок:
- • в программе имеется открывающая операторная скобка (например, DO WHILE или DO CASE либо IF. ), но отсутствует закрывающая (ENDDO или ENDCASE либо ENDIF)’,
- • в программе команда USE. использована для файла, не имеющего формата .dbf;
- • в программе команда USE. использована с именем файла, который отсутствует в рабочем каталоге диска;
- • для приема ввода (в команде GET. ) использовано обозначение переменной, которая не была определена выше (отсутствует команда присваивания некоторого значения этой переменной до выполнения команды GET. или отсутствует опция DEFAULT в этой команде);
- • не совпадает число формальных и фактических параметров в программе и подпрограмме (в Visual FoxPro эта ошибка диагностируется только тогда, когда формальных параметров меньше, чем фактических. Лишние формальные параметры не вредят программе, так как не используются).
Примеры синтаксических ошибок — любые описки в командах.
21. Отладка программ [Универсальный программист]
Visual FoxPro автоматически приостанавливает выполнение программы при наличии структурных и синтаксических ошибок и выводит сообщение о причине приостановки с запросами: “Cancel? Suspend? Ignore ?“
Для отладки наиболее полезен ответ Suspend, после которого программа приостанавливается, управление передается в командное окно и можно запросить значения любой переменной или просмотреть файл либо выполнить любую команду в диалоге. После анализа можно продолжить выполнение программы с помощью команды системного меню PROGRAM/RESUME (CTRL+M).
Отладочный режим в Visual FoxPro можно задать совокупностью команд из группы SET:
- • SET STEP ON — пошаговый режим работы программы;
- • SET ECHO ON — эхо-сопровождение программы (при этом текст каждой очередной команды перед выполнением выводится на экран);
- • SET TALK ON — режим выдачи отчета Visual FoxPro о выполнении каждой команды (на экран).
Автоматизацию процесса отладки можно обеспечить средствами отладчика, который представляет собой мощное средство, предназначенное для тестирования приложений. Отладчик позволяет:
- 1) показывать трассировку выполнения программы (вывод в окно Trace — Visual FoxPro Debugger текста программы с помощью меню File/ Open)’,
- 2) устанавливать точки останова точек приостановки программы (Breakpoints); просмотреть и изменить значения переменных. С помощью меню отладчика Window вызывается окно Watch (Alt+З), которое предназначено для слежения за изменением переменных в ходе выполнения программы;
- 3) отслеживать происходящие события:
- • можно установить режим вывода отчета о выполнении каждой команды с помощью всплывающего меню. Для этого надо нажать на правую кнопку мыши в области окна отладчика и в появившемся всплывающем меню выбрать команду TRACE BETWEEN BREAKS’,
- • можно установить темп прохождения программы с помощью меню отладчика Debug/Throttle. появится диалог Execution Throttle, в котором можно ввести интервал времени между выполнением команд — от 0 до 5,5 с;
- • DEBUG/ STEP INTO (F8) — осуществляет пошаговое выполнение программы;
- • DEBUG/ STEP OVER (F6) — осуществляет вызов процедур в качестве одного шага;
- • DEBUG/ STEP OUT (Shift+F7) — выходит из выполняемой в данный момент программы и останавливается на первой строке после команды, вызвавшей текущую программу;
- • RUN ТО CURSOR (F7) — осуществляет выполнение программы до текущего положения курсора.
Рекомендации по размещению точек приостановки программ при отладке (Breakpoints):
Профессиональная отладка программ | Ведение логов | Сообщения об ошибках в программе | debug
- • перед обращением к подпрограмме в головной программе: при этом после приостановки следует проверить (либо с помощью окна Debug, либо в командном окне), какие значения приняли все фактические параметры, передаваемые в подпрограмму, а также все переменные памяти, объявленные как глобальные (PUBLIC);
- • после входа в подпрограмму (ниже команды PARAMETERS)-. при этом после приостановки следует проверить, какие значения приняли все формальные параметры после приема фактических в подпрограмме, а также все переменные памяти, объявленные как глобальные (PUBLIC);
- • до входа в сложные программные конструкции (цикла DO . ENDDO, ветвления IF. ENDIF, выбора DO CASE. ENDCASE): при этом после приостановки следует проверить, какие значения приняли переменные памяти и поля таблицы, подлежащие изменению внутри цикла (номер записи, имя и номер поля, значения переменных, участвующих в организации цикла);
- • внутри цикла (после команды изменения значения переменной памяти, задающей номер цикла): при этом несколько (не менее двух) циклов следует выполнить в пошаговом режиме и проверить, правильно ли изменяются значения переменных памяти, участвующих в организации цикла;
- • после выхода из сложных программных конструкций (цикла DO. ENDDO, ветвления IF. ENDIF, выбора DO CASE. ENDCASE): при этом после приостановки следует проверить, какие значения приняли переменные памяти и поля базы данных после выхода из цикла (номер записи, имя и номер поля, значения переменных, участвующих в организации цикла).
Контрольные вопросы
- 1. Как подсчитать размер таблицы?
- 2. Какие типы выражений допустимы в VFP?
- 3. Как происходит объявление типа переменной?
- 4. Назовите команды открытия и закрытия таблицы.
- 5. Каково назначение указателя записей? Как проанализировать его положение?
- 6. Какие команды обеспечивают просмотр записей таблицы?
- 7. Какие команды обеспечивают перемещение указателя записей?
- 8. Для чего нужны окна редактирования и какие они бывают?
- 9. С помощью каких опций происходит настройка Browse-окна?
- 10. Можно ли в окна редактирования выводить записи из разных таблиц?
- 11. Какие способы добавления записей в таблицу вы знаете?
- 12. Каким образом происходит удаление записей в таблице?
- 13. Как удалить следующие три записи, начиная с пятой?
- 14. С помощью какой команды можно подавить обработку записей, помеченных на удаление?
- 15. Какая команда реализует создание индекса в таблице?
- 16. Какие механизмы отбора записей вы знаете?
- 17. С помощью какой команды можно установить связь между таблицами?
- 18. Какой метод положен в основу алгоритма ускоренного поиска записи?
- 19. Как осуществить поиск по ключу, заданному приблизительно?
- 20. Как работает функция SEEK?
- 21. Как изменить главный индексный файл?
- 22. Какой вид цикла характерен только для баз данных?
- 23. Для чего используются массивы в программах обработки?
- 24. Какая функция реализует копирование одного массива в другой?
- 25. В чем отличие команд SCATTER от COPY, GATHER от APPEND?
- 26. Какие значения принимают элементы массива сразу после объявления?
Источник: bstudy.net
3.2 – Процесс отладки
Допустим, вы написали программу, и она работает некорректно – весь код компилируется нормально, но при запуске вы получаете неверный результат. Где-то вы допустили семантическую ошибку. Как ее найти? Если вы следовали лучшим практикам, написали небольшой фрагмент кода, а затем протестировали его, у вас может быть представление о том, где находится ваша ошибка. Или вы можете вообще не догадываться.
Все ошибки проистекают из простой предпосылки: то, что вы считали правильным, неверно. На самом деле выяснить, где эта ошибка, может быть непросто. В этом уроке мы опишем общий процесс отладки программы.
Поскольку мы еще не рассмотрели очень много тем о C++, наши примеры программ в этой главе будут довольно простыми. Из-за этого некоторые из показываемых здесь приемов могут показаться чрезмерными. Однако имейте в виду, что эти методы предназначены для использования с более крупными и сложными программами и будут более полезны в тех условиях (там, где они вам нужны больше всего).
Общий подход к отладке
После выявления проблемы ее отладка обычно состоит из пяти шагов:
- найдите основную причину проблемы (обычно это неработающая строка кода);
- убедитесь, что вы понимаете, почему возникает проблема;
- определите, как вы решите проблему;
- устраните проблему, вызвавшую неисправность;
- повторите тест, чтобы убедиться, что проблема устранена и не возникло никаких новых проблем.
Давайте воспользуемся аналогией из реальной жизни. Допустим, однажды вечером вы идете взять лед из автомата для льда в морозильной камере. Вы подносите чашку к дозатору, нажимаете, и… ничего не выходит. Ой. Вы обнаружили какой-то дефект.
Чтобы вы сделали? Вы, вероятно, начнете расследование, чтобы выяснить, сможете ли вы определить основную причину проблемы.
Найдите первопричину: поскольку вы слышите, как дозатор льда пытается подать лед, вероятно, это не сам механизм подачи льда. Итак, вы открываете морозильную камеру и исследуете лоток для льда. Никакого льда. Это основная причина проблемы? Нет, это еще один симптом. После дальнейшего осмотра вы определяете, что льдогенератор не производит лед.
Проблема в льдогенераторе или в чем-то другом? Морозильник всё еще холодный, водопровод не забит, и всё остальное вроде работает, поэтому вы делаете вывод, что основная причина в том, что льдогенератор не работает.
Разберитесь в проблеме: в данном случае это просто. Ледогенератор не делает лед.
Определите способ исправления. На этом этапе у вас есть несколько вариантов исправления. Вы можете обойти проблему (купить в магазине пакеты со льдом). Вы можете попытаться провести дальнейшую диагностику льдогенератора, чтобы увидеть, есть ли деталь, которую можно отремонтировать. Вы можете купить новый льдогенератор и установить его вместо нынешнего.
Или вы можете купить новую морозильную камеру. Вы решили купить новый льдогенератор.
Устраните проблему: как только льдогенератор доставлен, вы устанавливаете его.
Повторное тестирование: после повторной подачи электропитания и ожидания в течение ночи ваш новый льдогенератор начинает делать лед. Новых проблем не обнаружено.
Теперь давайте применим этот процесс к нашей простой программе из предыдущего урока:
#include // Сложит два числа int add(int x, int y) < return x — y; // функция должна складывать, но это не так >int main() < std::cout
Этот код хорош в одном: ошибка очень очевидна, потому что неправильный ответ выводится на экран в строке 11. Это дает нам отправную точку для нашего исследования.
Найдите основную причину: в строке 11 мы видим, что мы передаем литералы в качестве аргументов (5 и 3), поэтому здесь нет места для ошибки. Поскольку входные данные для функции add правильные, а выходные данные – нет, совершенно очевидно, что неправильное значение должна давать функция add . Единственная инструкция в функции add – это инструкция return , которая и должна быть виновником. Мы нашли проблемную строку. Теперь, когда мы знаем, на чем сосредоточить наше внимание, вы, вероятно, заметите, что мы вычитаем, а не складываем.
Разберитесь в проблеме: в этом случае очевидно, почему генерируется неправильное значение – мы используем неправильный оператор.
Определите способ исправления: мы просто заменим operator- на operator+ .
Устраните проблему: это фактически замена operator- на operator+ и перекомпиляция программы.
Повторное тестирование: после внесения изменений повторный запуск программы покажет, что наша программа теперь выдает правильное значение 8. Для этой простой программы это всё, что необходимо для тестирования.
Этот пример тривиален, но он иллюстрирует основной процесс, который вы пройдете при диагностике любой программы.
Источник: radioprog.ru
Описание процесса отладки программы
Отладка — этап разработки компьютерной программы, на котором обнаруживают, локализуют и устраняют ошибки. Чтобы понять, где возникла ошибка, приходится:
· узнавать текущие значения переменных;
· выяснять, по какому пути выполнялась программа.
Существуют две взаимодополняющие технологии отладки.
· Использование отладчиков — программ, которые включают в себя пользовательский интерфейс для пошагового выполнения программы: оператор за оператором, функция за функцией, с остановками на некоторых строках исходного кода или при достижении определённого условия.
· Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода — на экран, принтер, громкоговоритель или в файл. Вывод отладочных сведений в файл называется журналированием.
Процесс отладки выполняется примерно по такому алгоритму: после того как написан рабочий код производятся тестовые запуски программы на различных наборах тестовых данных. При этом тестер или программист заранее должны получить контрольный результат, с которым будет идти сверка работы проверяемого кода. Например, заранее произвести вычисления.
В случае обнаружения расхождений между контрольным и фактическим результатами, начинается поиск проблемного участка кода и выявление ошибок вышеуказанными способами. Сейчас получают довольно мощное распространение средства автоматического тестирования исходного кода программ. Основной прием здесь это создание тестов исходного текста, которые будут применены к тестируемому участку кода, в системе тестирования сообщит об их результатах.
Тестирование программного обеспечения — процесс исследования программного обеспечения (ПО) с целью получения информации о качестве продукта.
Существует множество подходов к решению задачи тестирования и верификации ПО, но эффективное тестирование сложных программных продуктов — это процесс в высшей степени творческий, не сводящийся к следованию строгим и чётким процедурам или созданию таковых.
Качество программных средств можно определить как совокупную характеристику исследуемого ПО с учётом следующих составляющих:
Обработка ошибок в программе
Возникновение ошибок — это часто встречающаяся неприятность в программном обеспечении. Для получения нормальных результатов работы, пользователь должен уметь вовремя замечать и устранять возникающие ошибки.
Самый лучший способ повысить качество ПО это стараться не допускать ошибок в процессе ввода исходного текста.
Первый шаг на пути предотвращения ошибок это осознание того, что ошибки действительно можно предотвратить. Больше всего препятствует контролю над ошибками распространенное убеждение в том, что ошибки неизбежны. Ошибки сами по себе не появляются, их вносит в текст разработчик.
В ходе проверки программного комплекса было обнаружено наличие ошибок таких как:
Неправильная работа запросов (ошибка при вводе формулы). Эти ошибки были устранены путем введения правильных формул.
Ошибка при вводе фамилии клиента, при вводе даты несоответствующего формата, при вводе несуществующего номера абонента.
Эти ошибки были устранены путем правильного ввода соответствующих сведений.
Также в данной программе ошибка возникает, например, при вводе данных неправильного типа, противоположно указанных в базе данных. Примером является введение в заявление любого типа вместо цифр номера паспорта символов, т.к. тип данных данного поля является числовой.
Инструкция пользователю
Разработанную программу можно запустить несколькими способами. Например, из программы Microsoft Access из папки, в которой установлена программа «Подключение абонентов к сети». Рекомендуется запустить программу, используя ярлык на Рабочем столе.
После запуска программы «Подключение абонентов к сети» на экране появляется форма запуска программы, в которой имеются две кнопки: кнопка запуска главной формы проекта и кнопка выхода.
При нажатии на кнопку запуска программы на экране появляется главная кнопочная форма проекта.
Кнопочная форма — обыкновенная форма с кнопками, обеспечивающая возможность выполнения запросов, открытия форм и вывод на печать отчетов.
Главная кнопочная форма проекта имеет 3 вкладки: Формы, Шаблоны заявлений и Отчеты.
В первой вкладке «Формы» имеются 5 кнопок, отображающие переходы к соответствующим формам системы. Рассмотрим их подробнее:
Сведения о абонентах;
Сведения о номерах;
Сведения о тарифах.
1. Форма «Реестр подключений» позволяет ввести сведения о всех подключениях салона сотовой связи «РИТМ»
. Форма «Реестр заявлений» позволяет ввести сведения об операциях, связанных с заполнением заявлений по образцу.
1. Форма «Сведения о абонентах»» позволяет ввести данные о клиентах салона сотовой связи «РИТМ»
2. Форма «Сведения о номерах» позволяет ввести данные о абонентских номерах клиентов и подключенных тарифных планах.
. Форма «Сведения о тарифах» позволяет ввести данные об услугах тарифов сети «Мегафон»
Во второй вкладке «Шаблоны заявлений» представлены 6 кнопок, отображающие разновидности шаблонов заявлений по различным проблемам:
· Заявление на восстановление закрытого номера — оформляется в случае прекращения использования абонентского номера более 3-х месяцев по причине блокировки либо потери SIM-карты.
· Заявление на замену SIM карты — оформляется в случае порчи SIM-карты, не подлежащей физическому восстановлению.
· Заявление на перенос ошибочного платежа — оформляется в случае неверного занесения абонентского номера при пополнении счета. Возможно только в случае ошибки при занесении не более 2-х цифр номера.
· Заявление на переоформление договора — оформляется в случае переоформления номера телефона с одного абонента на другого при предоставлении паспорта и при условии регистрации данного номера.
· Заявление на подключение/отключение услуг — оформляется по просьбе абонента в случае добровольного подключения к предоставляемым услугам сети либо отказа от них.
· Заявление на смену абонентского номера — оформляется при добровольном согласии абонента сменить один номер телефона на другой. Возможна замена определенного количества цифр старого абонентского номера при условии, если данный номер не зарегистрирован уже на другого пользователя.
По итогам каждого дня формируется документ «Отправленные заявления», в котором указаны все сведения о абонентах и поданных ими заявлениях, которые рассматриваются и проверяются. Каждому заявлению присваивается статус: Выполнено/Не выполнено. После чего данные направляются в главный центр салона в г.Кисловодск. В итоге по полученным данным сведения заносятся в форму «Отправленные заявления».
Вкладка «Отчеты» главной кнопочной формы включает шесть простых отчетов: Реестр подключений, Реестр заявлений», «Сведения о абонентах», «Сведения о номерах», « Сведения о тарифах», «Отправленные заявления» и пять отчетов по выборке, созданных на основе запросов программы.
Рассмотрим подробнее простые отчеты:
1. Отчет «Реестр заявлений» включает поля: абонентский номер, дата заявления, абонентский номер новый, тип заявления, серия/номер паспорта, ФИО абонента.
2. Отчет «реестр подключений»включает поля: Абонентский номер, серия номер паспорта, дата подключения, тарифный план, подключен.
. Отчет «Сведения о абонентах» включает поля: ФИО абонента, серия номер паспорта, паспорт выдан, домашний адрес.
. Отчет «Сведения о номерах» включает поля: абонентский номер и тарифный план.
. Отчет « Сведения о тарифах» включает поля: тарифный план, Условия тарифа.
Программа формирует следующие отчеты на выборку:
· По номеру абонента;
· По статусу отправленного заявления;
· По тарифному плану;
· По типу заявления;
· По ФИО абонента.
1. Отчет «По номеру абонента» создавался на основе запроса «Выборка по абонентскому номеру».
В представленной форме размещено одно поле с фиксированным списком: Абонентский номер. Поле предназначено для ввода данных, с помощью которых совершается поиск по данному критерию.
В появившемся окне вводим номер телефона, после чего открывается отчет.
2. Отчет «По статусу отправленного заявления» создавался на основе запроса «Выборка по статусу отправленного заявления».
Выбор критерия поиска будет производиться по двум полям: Статус и Создан.
. Отчет «По тарифному плану» создавался на основе запроса «тарифный план по дате».
Выбор критерия поиска будет производиться по двум полям: Дата подключения и Тарифный план.
. Отчет «По типу заявления» создавался на основе запроса «Выборка по типу заявления».
Выбор критерия поиска будет производиться по двум полям: Дата подключения и Тип заявления.
. Отчет «По ФИО абонента» создавался на основе запроса «Выборка по ФИО».
Выбор критерия поиска будет производиться по одному полю: ФИО абонента.
Завершение работы с программой осуществляется с помощью нажатия на кнопку «Выход».
ЭКОНОМИЧЕСКАЯ ЧАСТЬ
Источник: infopedia.su
8.5. Для чего нужны отладка и тестирование? 8.6. В чем заключается отладка? 8.7. Что такое тест и тестирование?
8.8. Какими должны быть тестовые данные? 8.9. Из каких этапов состоит процесс тестирования?
Английский термин debugging («отладка») буквально означает «вылавливание жучков». Термин появился в 1945 г., когда один из первых компьютеров — «Марк-1» прекратил работу из-за того, что в его электрические цепи попал мотылек и заблокировал своими останками одно из тысяч реле машины.
8.6. В чем заключается отладка?
В современных программных системах (Turbo Basic, Turbo Pascal, Turbo C и др.) отладка осуществляется часто с использованием специальных программных средств, называемых отладчиками. Эти средства позволяют исследовать внутреннее поведение программы.
Программа-отладчик обычно обеспечивает следующие возможности:
- пошаговое исполнение программы с остановкой после каждой команды (оператора);
- просмотр текущего значения любой переменной или нахождение значения любого выражения, в том числе, с использованием стандартных функций; при необходимости можно установить новое значение переменной;
- установку в программе «контрольных точек», т.е. точек, в которых программа временно прекращает свое выполнение, так что можно оценить промежуточные результаты, и др.
При отладке программ важно помнить следующее:
- в начале процесса отладки надо использовать простые тестовые данные;
- возникающие затруднения следует четко разделять и устранять строго поочередно;
- не нужно считать причиной ошибок машину, так как современные машины и трансляторы обладают чрезвычайно высокой надежностью.
8.7. Что такое тест и тестирование?
Как бы ни была тщательно отлажена программа, решающим этапом, устанавливающим ее пригодность для работы, является контроль программы по результатам ее выполнения на системе тестов.
Программу условно можно считать правильной, если её запуск для выбранной системы тестовых исходных данных во всех случаях дает правильные результаты. |
Но, как справедливо указывал известный теоретик программирования Э. Дейкстра, тестирование может показать лишь наличие ошибок, но не их отсутствие . Нередки случаи, когда новые входные данные вызывают «отказ» или получение неверных результатов работы программы, которая считалась полностью отлаженной.
Для реализации метода тестов должны быть изготовлены или заранее известны эталонные результаты.
Вычислять эталонные результаты нужно обязательно до, а не после получения машинных результатов. |
В противном случае имеется опасность невольной подгонки вычисляемых значений под желаемые, полученные ранее на машине.
8.8. Какими должны быть тестовые данные?
Тестовые данные должны обеспечить проверку всех возможных условий возникновения ошибок:
- должна быть испытана каждая ветвь алгоритма;
- очередной тестовый прогон должен контролировать нечто такое, что еще не было проверено на предыдущих прогонах;
- первый тест должен быть максимально прост, чтобы проверить, работает ли программа вообще;
- арифметические операции в тестах должны предельно упрощаться для уменьшения объема вычислений;
- количества элементов последовательностей, точность для итерационных вычислений, количество проходов цикла в тестовых примерах должны задаваться из соображений сокращения объема вычислений;
- минимизация вычислений не должна снижать надежности контроля;
- тестирование должно быть целенаправленным и систематизированным, так как случайный выбор исходных данных привел бы к трудностям в определении ручным способом ожидаемых результатов; кроме того, при случайном выборе тестовых данных могут оказаться непроверенными многие ситуации;
- усложнение тестовых данных должно происходить постепенно.
Пример. Система тестов для задачи нахождения корней квадратного уравнения ax 2 + bx + c = 0 :
Номер теста | Проверяемый случай | Коэффициенты | Результаты | ||
a | b | c | |||
1 | d > 0 | 1 | 1 | -2 | x1 = 1, x2 = -2 |
2 | d = 0 | 1 | 2 | 1 | Корни равны: x1 = -1, x2 = -1 |
3 | d < 0 | 2 | 1 | 2 | Действительных корней нет |
4 | a = 0, b = 0, c = 0 | Все коэффициенты равны нулю. x — любое число | |||
5 | a = 0, b = 0, c № 0 | 2 | Неправильное уравнение | ||
6 | a = 0, b № 0 | 2 | 1 | Линейное уравнение; один корень: x = -0.5 | |
7 | a № 0, b № 0, c = 0 | 2 | 1 | x1 = 0, x2 = -0.5 |
8.9. Из каких этапов состоит процесс тестирования?
Процесс тестирования можно разделить на три этапа.
Проверка в нормальных условиях.
Предполагает тестирование на основе данных, которые характерны для реальных условий функционирования программы.
Проверка в экстремальных условиях.
Тестовые данные включают граничные значения области изменения входных переменных, которые должны восприниматься программой как правильные данные. Типичными примерами таких значений являются очень маленькие или очень большие числа и отсутствие данных.
Еще один тип экстрем аьных условий — это граничные объемы данных, когда массивы состоят из слишком малого или слишком большого числа элементов.
Проверка в исключительных ситуациях.
Проводится с использованием данных, значения которых лежат за пределами допустимой области изменений.
Известно, что все программы разрабатываются в расчете на обработку какого-то ограниченного набора данных. Поэтому важно получить ответ на следующие вопросы:
? Что произойдет, если программе, не расчитанной на обработку отрицательных и нулевых значений переменных, в результате какой-либо ошибки придется иметь дело как раз с такими данными?
? Как будет вести себя программа, работающая с массивами, если количество их элементов певысит величину, указанную в объявлении массива?
? Что произойдет, если числа будут слишком малыми или слишком большими?
Наихудшая ситуация складывается тогда, когда программа воспринимает неверные данные как правильные и выдает неверный, но правдоподобный результат.
Программа должна сама отвергать любые данные, которые она не в состоянии обрабатывать правильно.
Источник: www.examen.ru
Отладка приложений
В этом разделе мы перейдём от теории к практике и рассмотрим некоторые аспекты отладки приложений.
Отладочные и финальные версии
Одной из самых коварных ошибок, которые подстерегают разработчика на Visual C++, является ошибка, которая возникает только в финальной версии приложения (release version), когда оно, казалось бы, уже полностью отлажено. В ряде статей подробно рассматриваются возможные причины этого явления (рекомендую прочитать перевод статьи Джозефа Ньюкамера «Как пережить release-версию» (http://rsdn.ru/article/?vcpp/survrls.xml), посвящённой этому вопросу). Мы же поговорим о том, что нужно делать, чтобы найти и исправить ошибку.
Начинать поиск ошибки следует с отладочной версии программы. В первую очередь внимательно просмотрите предупреждения, которые выдаёт компилятор. Возможно, одно из них указывает на причину проблемы. Лучше всего переключить компилятор в режим предупреждений четвертого уровня (4 level warnings).
При этом действительно нежелательные предупреждения (в том числе предупреждения в стандартных заголовочных файлах Visual C++) можно отключить директивой препроцессора #pragma warning . Желательно полностью избавиться от предупреждений, прежде чем двигаться дальше. Кроме этого, просмотрите содержимое окна Debug после завершения программы. Возможно, вы обнаружите диагностические сообщения о записи в уже освобождённый блок памяти, о выходе за границы динамического массива или о других подобных ошибках. Если в настройках проекта не указан ключ /GZ, добавьте его (для этого нужно раскрыть окно Project->Settings , перейти на закладку C/C++ в категорию General и вручную вписать ключ в окно Project Options ). Этот ключ позволяет найти в отладочной версии некоторые ошибки, характерные для финальной версии. Для этой цели компилятор включает в программу дополнительные проверки:
- Все неинициализированные локальные переменные заполняются значением 0xCC. Обращение по неинициализированному указателю с таким значением гарантированно приведёт к нарушению доступа. Программа будет приостановлена, и вы сможете увидеть в отладчике точное местонахождение проблемной строчки.
- Значения указателя стека при входе и выходе из функции проверяются на равенство. Несовпадение означает, что стек испорчен (например, по причине записи за границу локального массива), и программа выдаст сообщение об ошибке.
- Значения указателя стека до и после вызова функции также проверяются на равенство. Если обнаружено несовпадение, программа выдаёт ошибку. Благодаря этому можно обнаружить ошибки, связанные с вызовом функции по указателю, у которого неверно задан набор параметров или соглашение о вызове. Вот пример такой ошибки:
HMODULE hKern = GetModuleHandle(_T(«kernel32.dll»)); // «забыли» __stdcall DWORD (/*__stdcall*/ *pRegisterServiceProcess)(DWORD, DWORD); (FARPROCRegisterServiceProcess»); pRegisterServiceProcess(NULL, 1); // некорректный вызов!
Если ошибка до сих пор не найдена, придётся перейти непосредственно к отладке финальной версии.
Прежде всего, существует очень небольшая вероятность того, что ошибку в программу внёс оптимизатор Visual C++. Чтобы выяснить этот вопрос, отключите оптимизацию. Для этого нужно раскрыть окно Project->Settings , перейти на закладку C/C++ в категорию General и задать Optimizations: Disable (Debug) . Если ошибка исчезла, оптимизацию придётся включить снова, чтобы найти проблемное место. Если же нет, не включайте её, так как это упростит пошаговую отладку (не будет сюрпризов вроде выкинутого компилятором из программы ненужного, по его мнению, кода).
Далее следует включить генерацию отладочных символов для финальной версии, чтобы отладчик мог показывать в процессе отладки исходный код программы, а не её ассемблерные листинги. Для этого нужно в очередной раз раскрыть окно Project->Settings , перейти на закладку C/C++ в категорию General и установить режим Debug info: Program Database for Edit and Continue . А на закладке Link в категории General следует установить флажок Generate Debug Information .
Некоторые считают, что после отключения оптимизации и генерации отладочных символов финальная версия ничем не отличается от отладочной. Это не так. Во-первых, отладочная версия программы линкуется с отладочной версией библиотеки языка C, а финальная версия – с обычной.
Во-вторых, в финальной версии не определяется макрос _DEBUG , что приводит к удалению из программы всех диагностических проверок. Есть и другие, менее заметные отличия. Например, в финальной версии не происходит инициализации переменных и областей памяти специальными отладочными значениями, типа 0xCD, 0xCC. Данная помощь компилятора выливается в то, что многие проверки указателей переменных, дающие стабильный результат в отладочной версии, приводят к нестабильностям в финальной версии.
Если ошибка появляется только при включённой оптимизации, её можно исправить одним из следующих способов.
- Отказаться от оптимизации, либо включить её выборочно для отдельных модулей. Можно также использовать директиву #pragma optimize для тонкой настройки оптимизации в пределах модуля.
- Переписать код другим способом – возможно, в изменённом варианте он будет скомпилирован и оптимизирован без ошибок.
В большинстве случаев ошибки, внесённые оптимизатором, являются следствием ошибок в вашей программе. Подробнее об этом можно прочитать в уже упомянутой мною статье «Как пережить release-версию».
Отладка приложений, запускаемых другими приложениями
Если приложение, которое необходимо отладить, запускается из другого приложения (в частности, это относится к локальным COM-серверам и сервисам Windows NT), задача несколько усложняется. Необходимо подключить отладчик к отлаживаемому процессу до того, как в нём выполнится ошибочный код. Для этого можно использовать следующие подходы.
Ручное подключение отладчика к процессу
Вы уже знаете, что подключить отладчик к уже запущенному процессу можно двумя способами: из Task Manager’а или посредством команды Build->Start Debug->Attach to Process .
ПРИМЕЧАНИЕ
Если вы используете команду Attach to Process для присоединения к сервису, не забудьте установить галочку Show System Processes , чтобы увидеть его в списке процессов. Для отладки сервисов вам необходимы права администратора (точнее, учетная запись должна обладать привилегией SeDebugPrivilege).
Недостаток такого подхода заключается в том, что от запуска процесса до присоединения отладчика проходит некоторое время, за которое часть программы успевает выполниться. Это может быть как раз та часть, которая вас больше всего интересует. В этом случае следует использовать следующий метод.
Использование DebugBreak
Функцию DebugBreak можно использовать, чтобы прервать программу в самом начале её работы, например:
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
Вызов функции DebugBreak эквивалентен срабатыванию точки останова. Если программа выполняется без отладчика, точка останова ничем не отличается от любого другого исключения. Поэтому система приостановит программу и выдаст знакомое окно Application Error (рис. 10).
Рисунок 10. Исключение типа Breakpoint
Нажимайте Cancel (режим Just-in-time debugging в Visual C++ должен быть включён!), и отладчик будет присоединён к программе в самом начале её выполнения. Этот способ можно использовать на всех платформах, но он недостаточно надёжен (исключение может быть кем-то перехвачено, и окно Application Error никогда не появится). Так, например, COM+ перехватывает это исключение и возвращает клиенту ошибку в виде HRESULT.
Автоматическое подключение отладчика к процессу
В Windows NT4 и выше можно заставить систему присоединять отладчик к некоторому процессу всякий раз, когда он запускается. Для этого запустите редактор реестра, раскройте ключ HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options и добавьте в него подключ, имя которого совпадает с именем exe-файла вашего приложения (без пути!). Затем создайте в этом подключе строковый параметр Debugger и запишите в него полный путь к отладчику Visual C++ (этот путь можно позаимствовать из свойств ярлыка Microsoft Visual C++ 6.0).
С параметром Debugger связано одно неприятное ограничение: длина пути к отладчику не должна превышать 64 символа. Путь к каталогу, в который Visual C++ ставится по умолчанию, обычно бывает длиннее. В этом случае нужно найти способ записать путь в более компактной форме – например, сделать каталог с Visual C++ разделяемым (shared) и задать в параметре Debugger его сетевое имя.
После этого приложение будет всегда запускаться под управлением отладчика. Чтобы отключить этот режим, удалите из реестра ключ, связанный с вашим приложением
Что делать дальше
После того, как отладчик присоединён к приложению, порядок действий может быть примерно таким.
- Если приложение продолжает выполняться, остановите его (команда Debug->Break )
- Убедитесь, что отладочные символы для приложения загружены. Для этого откройте окно Debug и просмотрите сообщения отладчика. Если вы увидите строчку вида «Loaded symbols for «, всё в порядке. Если же обнаружится строчка «Loaded , no matching symbolic information found», значит, отладчик не смог найти отладочные символы.
Файлы с отладочными символами должны находиться в том же каталоге, что и программа, или же в каталоге, в который их изначально поместил компилятор.
- Откройте файлы с исходными текстами программы ( File->Open ) и разместите в нужных местах точки останова.
- Возобновите работу приложения.
После этого сеанс отладки будет протекать, как обычно.
Отладка сервисов
DВсе сервисы Windows NT запускает Диспетчер управления службами (Service Control Manager, SCM). Присоединить отладчик к процессу сервиса можно как в момент его запуска, так и позже. Для этого можно использовать методы, изложенные в предыдущем разделе. Тем не менее, сервисы имеют несколько особенностей, о которых следует упомянуть.
Упрощенный вариант отладки
Так как любой сервис является обычным приложением Windows, в большинстве случаев его можно запустить как любой другой исполняемый файл и отлаживать в обыкновенном режиме. Для сервисов, созданных с помощью ATL Wizard, генерируется код, который позволяет зарегистрировать этот сервис не только в качестве сервиса, но и в качестве обыкновенного локального COM-сервера. При этом становятся доступными стандартные методы отладки EXE-приложений. Такой режим не всегда подходит, так как приложение, работающее в режиме сервиса, имеет свои особенности.
Отладка кода запуска
В Windows 2000 сервису даётся 30 секунд с момента запуска, чтобы выполнить инициализацию и вызвать функцию StartServiceCtrlDispatcher . Если он этого не сделает, SCM принудительно завершит весь процесс. Поэтому сеанс отладки кода запуска сервиса также может продолжаться не более 30 секунд. Если за это время выявить проблему в отладчике не удаётся, придётся использовать «доисторические методы», связанные с выводом массы диагностической информации в процессе работы программы и последующим анализом полученных данных.
Режим Allow Service To Interact With Desktop
В процессе отладки сервиса (как и любого другого приложения) удобно использовать отладочные макросы (такие, как _ASSERT) для проверки различных условий по ходу программы. Чтобы сообщения от этих макросов могли появляться на экране, необходимо открыть свойства сервиса, перейти на закладку Log On, убедиться, что сервис запускается под учетной записью SYSTEM, и установить флажок Allow Service To Interact With Desktop . Когда сервис полностью отлажен, этот флажок можно будет отключить.
Отладка локальных COM-серверов
При отладке локальных COM-серверов удобно использовать режим OLE RPC debugging . В этом режиме можно «заходить» в отладчике прямо в методы COM-сервера (для этого «на лету» запускается второй экземпляр отладчика и подключается к серверу). Режим OLE RPC debugging включается в окне Tools->Options (закладка Debug ). Чтобы он стал доступен, необходимо предварительно включить режим Just-in-time debugging .
Эта статья опубликована в журнале RSDN Magazine #0. Информацию о журнале можно найти здесь
Источник: www.rsdn.org