Отладка программ с использованием отладчика. Лучшие инструменты пентестера: отладчики и дизассемблеры

Отладка Windows Service приложений не такая тривиальная задача как кажется. Проблема в том, что при отладке этого типа приложений нельзя воспользоваться стандартными средствами Visual Studio такими как точки останова (breakpoints) и прочими полезными инструментами. Всё из-за того, что Windows Service приложение не может быть зыпущено по F5 прямо из Visual Studio. Всё же, MSDN предлагает нам несколько способов для их отладки. Скорее всего многие разработчики даже и не сталкивались с ними до тех пор, пока не стали создавать свою первую службу. Это использование записей в журнал событий и подключение к процессу . Оба этих метода хорошо описаны в MSDN, но они позволяют произовдить отладку только уже запущенной службы. Из-за этого код, который производит сам запуск службы, в методе OnStart(), нельзя протестировать.

Ниже я хочу рассказать о способе которым можно обойти это ограничение, и тестировать свой сервис как обычное консольное приложение. И, следовательно, воспользоваться всем тем, что предлагает нам для этого Visual Studio.

Сначала нам нужно создать новый проект. Назовем его TestWinService.

Т.к. это служба, сразу же добавим к нему установищик. Нажимаем правой клавишей мыши на пустой области только что открывшегося файла и выбираем Add Installer.

Теперь добавим к нашему решению консольный проект, из которого мы, собственно, и будем производить отладку нашей службы. Сразу после создания нового проекта добавим к нему две ссылки. Одна на нашу службу, TestWinService, другая на System.ServiceProcess необходимую для вызова сервиса.

Теперь начинается самое интересное. Чтобы отладить код запускающий службу, нам нужно будет создать новый поток, который и будет делать всю необходимую работу. А также два метода – Start() и Stop() для его запуска и завершения. И, соответственно, вызовем их в методах включения и выключения службы. В итоге у нас получится что-то вроде этого.

Видно, что мы добавили тестовую строку и поставили на нее точку останова.
Теперь добавим в консольное приложение код, который будет эмулировать запуск и остановку службы. У нас должно получиться, что-то подобное на рисинке ниже.

Все готово! Остается только нажать F5 и убедиться, что отладчик остановился на тестовой строке.

С помощью этого метода отладка служб становится ничем не труднее отладки обычного консольного приложения. Надеюсь это кому-нибудь пригодиться.

Локализация и исправление ошибок называется отладкой . Отладка - это процесс обнаружения причин возникновения ошибки и ее последующего исправления (в отличие от тестирования, являющегося процессом обнаружения самого факта существования ошибки).

Отладка включает в себя элементы тестирования и разработки. На некоторых проектах отладка может занимать до 50 % всего времени разработки. Для многих программистов отладка - это самая трудная часть программирования. При соответствующем подходе количество ошибок, требующих отладки, должно сократиться, и отладка должна стать самой легкой частью; при таком подходе все ошибки сводятся к небольшим недосмотрам или опечаткам.

Как и тестирование, отладка не является способом улучшения качества ПО. Отладка - это всего лишь способ исправления дефектов в программе. Качество программ должно обеспечиваться аккуратным анализом требований или прототипированием, грамотным проектированием и использованием лучших практик кодирования.

Ошибки синтаксиса языка

Как правило, в абсолютном большинстве случаев ловятся на стадии компиляции программы, или же, если вы работаете с интерпретируемым языком типа Рег1 или РНР, то при первом интерпретировании программы. Но есть один существенный момент - когда выражение допустимо, но зависит от конкретного компилятора или интерпретатора. Например, в языке Си вполне допустимыми по синтаксису, но не по смыслу, являются выражения: э [ 1++] =±; ргл_г^:? ("%с! %с!" , ±++, л.++) ;. Результат этих строк не определен, так как неизвестно, в каком порядке будет инкрементироваться и вычисляться значение переменной /". Переменная не может более 1 раза присутствовать в выражении, если ее значение изменяется в ходе вычисления этого выражения.

Ошибки во время выполнения

К ошибкам во время выполнения программы относятся ошибки в логике и алгоритмах программы. Ошибки в логике программы связаны с неправильной записью алгоритма, например, вместо && вы написали || или поставили точку с запятой там, где ее не должно быть. К этому же классу ошибок относится неправильное обращение с памятью. В языке Си неправильное обращение с памятью является наиболее распространенной ошибкой программистов, причем не только новички, но и профессионалы нередко допускают ошибки подобного типа. Для языка Си - это один из самых больных вопросов и больших недостатков. Ошибки в алгоритме связаны с неправильным проектированием программы или же с изначально неправильно заложенной бизнес-логикой и функциональными требованиями. Пользователь ждет от программы то, что изначально от нее не требовалось. Ошибки во время выполнения - наиболее часто встречаемый тип ошибок, и, как правило, устранение таких ошибок не представляется чересчур сложной задачей.

Ошибки логики взаимосвязанных CGI-программ

Ошибки данного типа лежат во взаимосвязанных CGI-программах. Рассмотрим в качестве примера тестовую систему (см. сайт http://test.itsoft.ru). При сдаче теста в цикле работают два скрипта. Первый показывает вопрос, а второй проверяет правильность ответа. Если в тесте 10 вопросов, то эти CGI-скрипты вызываются парно в цикле 10 раз. Но что будет, если пользователь нажмет кнопку «Обновить» в броузере? Скрипт, который показывает вопрос, вызовется повторно. Что будет при разрыве модемного соединения? Отладка в таких системах значительно сложнее, так как вам придется наблюдать за выполнением ряда взаимосвязанных скриптов.

Ошибки многопользовательского доступа

Ошибки многопользовательских систем связаны с неправильным разграничением доступа к совместным ресурсам. Помимо файлов данных, записей в таблицах баз данных, общим ресурсов является генератор случайных чисел. На эти грабли нам пришлось наступить. Обязательно генерируйте случайные числа не только на основе времени, но и на основе уникального идентификатора процесса. В противном случае при выполнении в один и тот же момент времени двух копий одной CGI-программы вы получите одинаковые результаты для двух пользователей. Ошибки многопользовательского доступа сложны тем, что могут не проявлять себя очень долго, до тех пор, пока в один и тот же момент времени системой ни будет запущено несколько копий одной CGI-программы.

Невоспроизводимые ошибки

Невоспроизводимые ошибки представляют собой наиболее сложный тип ошибок. Например, в високосном году 29 февраля ваша система вдруг начала давать сбои, которые сами собой исчезают в невисокосном году. Но бывают ошибки, которые мистическим образом появляются и исчезают. В той же тестовой системе была непонятная ошибка, которая проявлялась 1 раз на несколько сот случаев. Непонятным образом некоторые студенты после сдачи теста получали не результаты, а сбой системы. На исправление этой ошибки ушло два рабочих дня. Оказалось, что проблема в скрипте на JavaScript, который отправлял данные HTML-формы на сервер после истечения допустимого времени ответа на вопрос. Проблема в том, что если время подходило к концу и пользователь нажимал кнопку «Ответить», а в это же время уже начала работать функция JavaScript form.submit(), то отправка данных HTML-формы происходила дважды, т. е. скрипт проверки правильности ответа вызывался 2 раза. А это за собой тянуло ошибку во взаимосвязанных CGI-скриптах, и внешнее проявление сбоя системы мы наблюдали уже при подсчете результатов, а не непосредственно сразу после двойной отправки HTML-формы. Сам код JavaScript был написан верно, и с теоретической точки зрения даже если пользователь нажимает кнопку «Отправить» в последнюю секунду, HTML-форма должна была отправляться только 1 раз. Но на практике все оказалось совсем по-другому. На самом деле ничего мистического нет, или, как говорится, чудес на свете не бывает. Просто невозможно воспроизвести условия, в которых наблюдалась невоспроизводимая ошибка. Надо искать в программе случайности: одновременный доступ к одному ресурсу, генератор случайных чисел, неинициализированные переменные, некорректная работа с памятью или преобразование типов, которые могут проявлять себя не каждый раз.

Ошибки инструментария и других компонентов системы

Ошибки самого компилятора или интерпретатора очень редки, но и такие бывают.

После классификации ошибок давайте рассмотрим методы их поиска. В первую очередь, один простой и, казалось бы, очевидный совет: «надо думать, анализировать, почему программа не работает так, как было задумано, что надо в ней исправить». Никакой самый навороченный отладчик за вас ошибку не найдет. Никакая самая лучшая методика не найдет и не ускорит поиск ошибки, если вы не «включите» мозги по полной программе и не сосредоточитесь целиком и полностью на поимке ошибки. Итак, допустим, вами, пользователем или тестирующим, было зафиксировано некорректное поведение программы. Что делать? Ниже перечислены методы в порядке их приоритетности, которые используют многие программисты.

Локализация ошибки. Программа - это черный ящик, который что-то принимает на вход и выдает что-то на выходе. Первое, что вам необходимо сделать, - понять, где именно в этом черном ящике происходит сбой. Для этого уменьшайте количество параметров, передаваемых на вход программы. Добейтесь двух малоразличимых наборов входных параметров, чтобы при одном из них программа работала, а при другом нет.

Отключение ненужных модулей программы. Закомментируйте все лишнее. Тем самым вы упростите вашу программу. Имеет смысл комментировать отдельные куски программы до тех пор, пока ошибка не исчезнет.

Использование отладчика. Возможности современных отладчиков перечислены ниже:

  • точки останова на конкретных строчках кода;
  • остановка на /7-й итерации цикла;
  • остановка при изменении переменных;
  • остановка при присваивании конкретного значения;
  • прохождение кода строчка за строчкой;
  • откат по программе (далеко не все);
  • исследование всех данных в программе, включая типы, определенные пользователем;
  • присваивание новых значений переменным;
  • продолжение исполнения программы;
  • многоязыковая отладка (язык1, язык2, ассемблер...);
  • запоминание установок.

Контрольные вопросы

  • 1. Какие виды ошибок существуют?
  • 2. Что такое тест? Какими свойствами должен обладать тест?
  • 3. Каковы критерии выбора тестов?
  • 4. Дайте краткую характеристику каждому критерию выбора теста.
  • 5. Опишите последовательность разработки тестов.
  • 6. Что входит в понятие надежности ПО?
  • 7. Какие виды отказов существуют?
  • 8. Каковы количественные характеристики надежности программ?
  • 9. Что представляют собой методы оценки и измерения характеристик надежности ПО?
  • 10. Перечислите достоинства парного программирования.

Введение 2

Определение программирования. Этапы создания программы 3

Отладка программы 6

Задача 2 и 3 9

Задача 4 и 5 12

Заключение 14

Список используемой литературы 15

Введение

Компьютерная техника и компьютерная технология прочно вошли в человеческую жизнь. Развитие научно-технического прогресса невозможно без автоматизации вычислительных процессов. Именно потребность в автоматизации вычислительных процессов стала первоначальным импульсом в развитии программирования.

Традиционная технология программирования формировалась на заре вычислительной техники, когда в распоряжении пользователей были ограниченные ресурсы ЭВМ, а разработчик программ был в то же время и главным ее пользователем. В этих условиях главное внимание обращалось на получение эффективных программ в смысле оптимального использования ресурсов ЭВМ.

В настоящее время, когда сфера применения компьютеров чрезвычайно расширилась, разработка и эксплуатация программ осуществляется, как правило, разными людьми. Поэтому наряду с эффективностью на первый план выдвигаются и другие важные характеристики программ такие, как понятность, хорошая документированность, надежность, гибкость, удобство сопровождения и т.п. Проблема разработки программ, обладающих такими качествами, объясняется трудоемкостью процесса программирования.

Для создания программы появляется необходимость придерживаться определенных принципов и новых технологий программирования.

В наше время из-за постоянного прогресса компьютерных технологий программирование играет важнейшую роль в жизнедеятельности человека.

Определение программирования. Этапы создания программы

Чтобы компьютер выполнил решение, какой либо задачи ему необходимо получить от человека инструкцию, как ее решать, набор таких инструкций для компьютера, направленной на решение какой-либо задачи называется – программой.

Программирование – процесс создания компьютерных программ или программного обеспечения с помощью языков программирования. Программирование сочетает в себе элементы фундаментальных наук, таких как математика, высшая математика и инженерия.

Язык программирования – формальная знаковая система, предназначенная для записи программ. Со времени создания первых программируемых машин человечество придумало уже более восьми с половиной тысяч языков программирования. Каждый год их число пополняется новыми. Некоторыми языками умеет пользоваться только небольшое число их собственных разработчиков, другие становятся известны миллионам людей. Профессиональные программисты иногда применяют в своей работе более десятка разнообразных языков программирования.

В процессе создания любой программы можно выделить следующую последовательность этапов:

1 этап. Постановка задачи: на этом этапе участвует человек хорошо представляющий предметную область задачи. Он должен четко определить цель, задачи, дать словесное описание содержания задачи и предложить общий подход к ее решению, анализируются характер и сущность всех величин, используемых в задаче, и определяются условия, при которых она решается, иначе говоря, на этом этапе формируется условие задачи. Этот этап очень важен, так как от правильного понимания целей и требований зависит в основном успех реализации создаваемой программы.

2 этап. Анализ задачи и моделирования: целью этого этапа является математическая модель или математическая постановка. На этом этапе выполняются следующие пункты

1) Определяются исходные данные и их типы.

2) Решение задачи описывается в виде аналитических зависимостей (уравнения, функции).

3) Определяются конечные данные и их типы.

Таким образом формируется математическая модель с определенной точностью, допущениями и ограничениями. При этом в зависимости от специфики решаемой задачи могут быть использованы различные разделы математики и других дисциплин.

3 этап. Алгоритмизация задачи и составление блок-схемы: выполняется на основе математического описания программы. На данном этапе составляется алгоритм решения задачи согласно действиям, задаваемым выбранным методом решения. Процесс обработки данных разбивается на отдельные относительно самостоятельные блоки, и устанавливается последовательность выполнения блоков. Разрабатывается блок-схема алгоритма.

4 этап. Программирование: на этом этапе алгоритм решения задачи переводится на конкретный язык программирования. Для программирования обычно используются языки высокого уровня, поэтому составленная программа требует перевода ее на машинный язык. После такого перевода выполняется уже соответствующая машинная программа.

5 этап. Отладка и тестирование программы: заключается в поиске и устранении синтаксических и логических ошибок в программе.

В ходе синтаксического контроля программы транслятором выявляются конструкции и сочетания символов, недопустимые с точки зрения правил их построения или написания, принятых в данном языке. Сообщения об ошибках компьютер выдает программисту, при этом вид и форма выдачи подобных сообщений зависят от вида языка и версии используемого транслятора. После устранения синтаксических ошибок проверяется логика работы программы в процессе ее выполнения с конкретными исходными данными.

6 этап. Исполнение отлаженной программы и анализ результатов: после отладки программы ее можно использовать для решения прикладной задачи. При этом обычно выполняется многократное решение задачи на компьютере для различных наборов исходных данных. Получаемые результаты интерпретируются и анализируются специалистом или пользователем, поставившим задачу.

Отладка программы

Несмотря на то, что создание программы происходит в несколько этапов, наиболее важным и трудоемким является этап отладки и тестирования программы. Именно на этом этапе устраняются все логические и синтетические ошибки в создаваемой программе.

Отладка – это деятельность, направленная на обнаружение и исправление ошибок в программе.

Тестирование – это процесс выполнения программы на некотором наборе данных, для которого заранее известен результат применения или известны правила поведения этих программ. Таким образом, отладку можно представить в виде многократного повторения трех процессов: тестирования, в результате которого может быть констатировано наличие ошибки, поиска места ошибки в программе и редактирования программы и документации с целью устранения обнаруженной ошибки. Таким образом, все вышесказанное можно представить формулой:

Отладка = Тестирование + Поиск ошибок + Редактирование.

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

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

Кроме использования встроенных программных отладчиков существуют и другие методы отладок программы: использование внутрисхемного эмулятора, отладка при помощи внешних программных отладчиков и отлаживаемым устройством с записанным в память программ двоичным кодом программы.

Внутрисхемный эмулятор с отображением переменных языка программирования на дисплее компьютера оказывает значительную помощь при отладке программ непосредственно на разрабатываемой аппаратуре. Этот метод отладки предоставляет наиболее удобную среду, когда можно непосредственно в отлаживаемом устройстве останавливать программу, контролировать выполнение программы непосредственно по исходному тексту программы, состояние внешних портов и внутренних переменных, как входящих в состав микросхемы, так и объявленных при написании исходного текста программы. До недавнего времени внутрисхемный эмулятор являлся отдельным устройством, подключаемым к разрабатываемой плате.

Встроенный программный отладчик, входящий в состав интегрированной среды программирования значительно упрощает процесс отладки программы. Но в тоже время она значительно замедляется.

Внешний программный отладчик. В некоторых случаях используется не интегрированная среда программирования, а отдельный транслятор с выбранного языка программирования. Так как объектные форматы различных трансляторов несколько отличаются друг от друга, то в качестве входного файла используется загрузочный модуль в двоичном формате.

Отладка программ заключается в проверке правильности работы программы и аппаратуры. Программа, не содержащая синтаксических ошибок, тем не менее, может содержать логические ошибки, не позволяющие программе выполнять заложенные в ней функции. Логические ошибки могут быть связаны с алгоритмом программы или с неправильным пониманием работы аппаратуры, подключённой к портам микроконтроллера.

Встроенный в состав интегрированной среды программирования отладчик позволяет отладить те участки кода программы, которые не зависят от работы аппаратуры, не входящей в состав микросхемы микроконтроллера. Обычно это относится к вычислению математических выражений или преобразованию форматов представления данных.Программирование является «отладка» программы , т. е. обнаружение и исправление ошибок, допускаемых при Программирование Основное средство отладки ...

  • Паскаль Отладка программ

    Реферат >> Информатика

    Логические операторы и операторы цикла. Отладка программ . Укороченная форма оператора if В... if. Средства среды программирования для отладки программ Среда Borland Pascal ... несколько встроенных инструментальных средств отладки программ . С некоторыми из них...

  • Программа по начислению заработной платы и налогов работникам фирмы

    Реферат >> Экономика

    Программного обеспечения: изучение постановки задачи; программирование и отладка программ ; описание контрольного примера; совместно с... машинного времени при отладке программы определяются путем умножения фактического времени отладки программы на цену...

  • Выполнение и отладка программ в интегрированной среде программирования Turbo Pascal (MS-Dos)

    Лабораторная работа >> Информатика, программирование

    Практического использования интегрированных сред программирования с целью выполнения и отладки программ на языке Паскаль. ТЕОРЕТИЧЕСКИЕ... СВЕДЕНИЯ Базовыми компонентами системы программирования Турбо...

  • Я решил проверить, как отладчик Bochs можно использовать для отладки загрузчика и внутренностей операционной системы. Эта статья описывает, что из этого получилось.

    Bochs у меня был установлен давно, я решил заглянуть в инсталляционный директорий и обнаружил, что у Bochs среди прочих выполнимых файлов есть два выполнимых файла bochs.exe и bochsdbg.exe:

    Чтобы протестировать загрузку, для начала беру простой Hello World загрузчик:

    Section .text use16 org 0x7C00 ; программа загружается по адресу 0x7C00 start: mov ax, cs mov ds, ax ; выбираем сегмент данных mov si, message cld ; направление для строковых команд mov ah, 0x0E ; номер функции BIOS mov bh, 0x00 ; страница видеопамяти puts_loop: lodsb ; загружаем очередной символ в al test al, al ; нулевой символ означает конец строки jz puts_loop_exit int 0x10 ; вызываем функцию BIOS jmp puts_loop puts_loop_exit: jmp $ ; вечный цикл message: db "Hello World!",0 finish: times 0x1FE-finish+start db 0 db 0x55, 0xAA ; сигнатура загрузочного сектора

    Записываю его в hello.asm, компилирую: nasm hello.asm -o hello.img
    Получаю файл hello, размером 512 байт. Это образ загрузочной дискеты. В первом секторе загрузочный сектор c программой «Hello world»

    Запускаю bochsdbg.exe. Открывается стартовое меню:

    Дважды кликаю в меню «Disk & Boot». Открывается меню настройки дисков. Указываю что флоппи диск читать из файла hello.img:

    Нажимаю OK, в стартовом меню нажимаю на Start. Открывается два окна, окно с виртуальной машиной, и окно с командной строкой для команд отладки. Команды отладки похожи на gdb. Например:

    • b 0x7c00 — установить breakpoint на инструкцию по адресу 0x7c00, что соответствует началу загрузочного сектора
    • c — продолжить выполнение (continue)
    • h — получить в помощь список возможных команд
    • h b — получить помощь по конкретной команде (в данном случае break)

    После команды ‘c’ (сontinue), Bochs продолжает выполнение и останавливается на первой команде загрузчика, как и хотелось. Чтобы по шагам отлаживаться даю команду ‘n’ (next). Предыдущую команду повторяю простым нажатием на ‘Enter’.

    У отладчика много разных команд. Например:

    • regs — показать содержимое регистров
    • sregs — показать содержимое сегментных регистров
    • x c хитрыми параметрами типа x /16b 0x7c00 — покажет содержимое 16 байт по адресу 0x7c00

    И т.д. помощь по командам можно получить из командной строки, с помощью команды ‘h’, как я писал выше. А также на сайте разработчиков есть справочник команд и много другой полезной информации, которой стоит пользоваться. Чтобы немного еще проиллюстрировать как это выглядит, еще пара скринов:

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

    Отладка программы - это специальный этап в разработке программы, состоящий в выявлении и устранении программных ошибок, факт существования которых уже установлен. Программные ошибки, как правило, делятся на три вида:

    1. Синтаксическая ошибка . Неправильное употребление синтаксических конструкций, например употребление оператора цикла For без то или Next.
    2. Семантическая ошибка . Нарушение семантики той или иной конструкции, например передача функции параметров, не соответствующих ее аргументам.
    3. Логическая ошибка . Нарушение логики программы, приводящее к неверному результату. Это наиболее трудный для "отлова" тип ошибки, ибо подобного рода ошибки, как правило, кроются в алгоритмах и требуют тщательного анализа и всестороннего тестирования.

    Поскольку безошибочное программирование почти невозможно, а ручная отладка немыслима, необходимы средства поиска ошибки (иногда это не так просто) и ее исправления. В других случаях можно просто обойти возможные появления ошибки, также используя специальные методы. Именно об этих средствах и методах пойдет речь в настоящем разделе.

    В каждой современной системе программирования существует специальное средство отладки программ - отладчик (debugger), который позволяет в режиме интерпретации установить контрольные точки, выполнить отдельные участки программы и посмотреть результаты работы операторов. Естественно, что редактор Visual Basic имеет подобное средство, с которым мы сейчас и познакомимся. В вышеописанной программе мы специально допустили ошибки, на примере которых и продемонстрируем работу отладчика VBA.

    Замечание

    Все ошибки располагаются в процедуре AssignTask, так что перед началом отладки вы можете проверить себя и попытаться отыскать их самостоятельно.

    Первый шаг отладки - это запуск компилятора: Debug > compile <имяПроекта>. Компилятор, просматривая код программы, найдет ошибку и выдаст сообщение: sub or Function not defined (Процедура или функция не определены), выделив место ошибки (creatitem) в теле процедуры.

    Итак, допущена синтаксическая ошибка, мы сделали опечатку (вместо createitem ввели creatitem), и компилятор стал расценивать это как вызов процедуры пользователя, которая нигде не объявлена. Быстро исправим эту оплошность, добавив злополучную е в код:

    Set tsk = Createltem(olTaskltem)

    Ошибка исправлена, можно возвращаться к первому пункту - запуску компилятора. На этот раз компиляция прошла успешно, и есть предпосылки к тому, что программа окончательно исправлена. Давайте запустим ее.

    Замечание

    Вообще же, в VBA нельзя говорить о запуске программы как таковой, поскольку в отличие от других языков программирования, в которых существует предопределенный способ определения того, с чего будет начинаться выполнение программы, в VBA такого предопределения нет. В VBA никакая процедура не является главной по умолчанию, нужно как-то указывать, с чего должно начинаться выполнение программы. Типовое решение автоматического запуска программы VBA - связывание "главной" процедуры с событием открытия документа, в котором находится проект.

    Запуск программы в VBA осуществляется разными способами. Уже упоминалась возможность запуска программы посредством нажатия клавиши или с помощью команды Run Sub\UserForm меню Run. Однако при таком вызове запускается активная процедура, т. е. процедура, в которой находится курсор. Другим Способом является вызов диалогового окна Macros из меню Tools. В этом окне можно выбрать запускаемую процедуру, не делая ее активной.

    Итак, мы запустили программу. Что же происходит? Сразу после запуска появляется диалоговое ОКНО об ошибке: Object variable or With block variable not set (объектная переменная или переменная блока with не определена) и четыре варианта продолжения работы с программой (рис. 22.6):

    1. Continue. Продолжить выполнение программы.
    2. End. Закончить выполнение программы.
    3. Debug. Прервать выполнение программы и перейти в режим отладки.
    4. Help. Вывести подробную справку об ошибке.

    Замечание

    Хотя в данном случае кнопка Continue не активна, она бывает очень полезна в ряде случаев. Например, при прерывании хода программы комбинацией клавиш + только для проверки контрольных значений в окне Immediate, когда нет необходимости переходить в режим отладки, если все значения удовлетворительны. Кнопка End используется для окончательного прерывания хода программы, как правило, когда ошибка сразу видна и не требует отладочных средств.

    Рис. 22.6. Диалоговое окно Run-time error "91"

    Выберем Debug. В этом случае окно с кодом программы становится активным и в нем выделяется (по умолчанию желтым цветом) оператор, на котором прервалось выполнение программы. Мы выбрали Debug, поскольку имеем достаточно большой опыт и по краткому описанию ошибки можем понять, в чем дело. Но вам мы советуем до определенного момента обращаться за разъяснением к справке, в которой подробно и на примерах описана ошибка, вызвавшая прерывание хода программы.

    В нашем же случае произошла семантическая ошибка: неправильное присваивание переменной значения ссылки на объект. Для устранения этой ошибки необходимо добавить оператор присваивания set перед переменной tsk. Давайте еще раз запустим программу. На этот раз она успешно завершилась, дойдя до конца и выдав сообщение "Задача успешно поручена".

    Вроде бы все работает, но мы протестировали только малую часть всех возможностей приложения, не будем останавливаться и посмотрим, что же сгенерировало наше мини-приложение. На рис. 22.7 изображен примерный вариант порученной задачи.

    Как видите, все параметры верны, кроме загадочного срока окончания задачи, который истекает через 5 дней, в то время как в диалоговом окне продолжительность проекта была равна 5 месяцам!!!

    Итак, наша программа фактически работает, собирает данные из разных источников, создает задачу и даже назначает ее, но неверно устанавливает срок ее окончания. Надо констатировать, что мы столкнулись с последним типом ошибки - логическим. Компилятор не может отследить подобного рода ошибки автоматически, но это может сделать программист, используя, конечно, всевозможные способы и средства отладки.

    Для отлова логических ошибок выполняется трассировка программы, т. е. выполнение программы или ее участка, сопровождающееся выводом в хронологической последовательности информации о событиях, связанных с выполнением программы. Давайте задумаемся, информацию о каких событиях мы хотели бы получить? Мы хотели бы получить и наблюдать измене ние переменных после выполнения операторов программы, причем желательно в пошаговом режиме, чтобы видеть процесс выполнения программы и иметь возможность тут же его исправить. Однако наблюдение всех переменных хоть и возможно, но малоэффективно.

    Рис. 22.7.

    Для этого необходимо предположить, в каких местах возможно появление ошибки, и расставить там специальные точки останова, чтобы остановиться и проверить значения переменных, когда программа дойдет до них. Таким образом, увидев, какой из операторов "лжет", можно приступить к его разбору. Идея отлова ясна, осталось только подготовить программу с помощью редактора к этой увлекательной процедуре.

    Чтобы создать точку останова, следует в отлаживаемой процедуре установить точку ввода в любом месте строки кода VBA, перед выполнением которой вы хотите остановить выполнение процедуры. Затем нужно выбрать команду > Debug > Toggle Breakpoint или просто нажать клавишу . При этом строка будет выделена коричневым цветом, а на левом поле окна кода появится жирная коричневая точка. Для снятия точки останова нужно еще раз повторить те же действия. Если напротив оператора стоит точка ос танова, это означает, что выполнение программы будет приостановлено перед выполнением этого оператора.

    Замечание

    Есть и более простой и, на наш взгляд, естественный способ установки точек останова: достаточно просто сделать щелчок мышью по серой полоске у левого края соответствующей строки кода. Снять эту точку можно повторным щелчком по жирной коричневой точке. Наконец, если вы хотите снять все ранее поставленные точки останова, вовсе необязательно снимать все эти точки поодиночке. Достаточно воспользоваться командой меню > Debug > Clear All Breakpoints.

    Наши подозрения вызвали следующие места программы, в которых мы и расставили точки останова (рис. 22.8).

    • Инициализация переменной tsk (чему равняется значение по умолчанию).
    • Вызов стандартной функции NOW (действительно ли возвращается текущее время).
    • Установка даты окончания задачи (правильно ли происходит суммирование).

    После расстановки точек останова необходимо, как было сказано, указать, значения каких переменных мы хотели бы наблюдать. Естественно, что мы выбрали значения полей tsk.startoate и tsk.DueDate. Для наблюдения за несколькими свойствами или переменными существуют специальные окна Locals Window и Watch Window. Эти окна можно открыть с помощью соответствующих кнопок на панели Debug или команд меню View.

    В окне локальных переменных можно наблюдать за значением всех локальных переменных выполняемой в данный момент процедуры, а окно контрольных значений предназначено для постоянного наблюдения за выбранными пользователем переменными или свойствами. Чтобы определить контрольное значение, достаточно выделить в окне модуля любую переменную, выражение или свойство и нажать кнопку Quick Watch на панели инструментов Debug. При этом появится диалоговое окно, в котором указано имя подпрограммы, само выражение, а также его текущее значение (рис. 22.8).

    Нажав на расположенную в правой части диалогового окна кнопку Add, можно переместить это выражение в список наблюдаемых контрольных значений в окне Watch. При этом в момент останова отлаживаемой программы весь список наблюдаемых выражений и их значения будут сразу же видны в соответствующем подокне, располагающемся обычно в нижней части экрана. Добавим переменную tsk. star toate вышеописанным способом. Чтобы наблюдать значение переменной, необходимо выполнить следующее действие.

    Рис. 22.8. Точки останова и диалоговое окно Quick Watch

    Пример 22.8. Добавление переменной в окно Add Watch

    {В окне Watch}

    1R Add Watch... (рис. 22.9)

    Expression:= tsk.StartDate

    Procedure AssignTask

    Итак, точки останова расставлены, окно Add Watch с наблюдаемыми переменными активно, следовательно, с замиранием сердца переходим к трассировке программы. Итак, нажимаем клавишу , как и предполагалось, перед инициализацией переменной происходит останов программы. Все правильно. Теперь давайте посмотрим, как изменились значения переменных В окне Add Watch: tsk.StartDate = 01:01:4501, tsk.StartDate = 01:01:4501, a duration = 5.

    Рис. 22.9. Диалоговое окно Add Watch

    Для единичного просмотра значения переменной можно просто подвести к ней указатель мыши, и вы увидите всплывающую подсказку. Например, duration = 5.

    Для дальнейшего пошагового выполнения программы можно воспользоваться одним из трех способов:

    1. Step Into. При нажатии клавиши выполняется очередной оператор, после чего выполнение программы приостанавливается и программа становится доступна для корректировки.
    2. Step Over. Нажатие комбинации клавиш + осуществляет вызов вспомогательных процедур и функций за один шаг, что дает возможность не задерживаться на их выполнении.
    3. Step Out. Данная комбинация клавиш ++ позволяет выйти из выполняемой вспомогательной процедуры, не дожидаясь конца ее пошагового выполнения.

    Итак, нам необходимо нажать клавишу и посмотреть, чему стало равно значение tsk.startDate. Как и следовало ожидать, переменной было присвоено значение 21.08.01. (текущая дата 21 августа 2001 года). Следовательно, функция Now работает корректно.

    Значение переменной duration равно 5, прибавляя его к значению текущей даты, мы прибавляем не месяцы (как хотелось бы), а дни. Исправим эту ошибку, изменив код ошибочной строки на следующий:

    DueDate = DateAdd("m", duration, .StartDate)

    Замечание

    Встроенная функция DateAdd предназначена для добавления или вычитания из даты указанного числа временных интервалов.

    В конце рассказа об отладчике мы решили на рис. 22.10 показать панель инструментов Отладка (Debug) с кнопками, используемыми при отладке, а в табл. 22.1 привести краткую справку по всем использованным и неиспользованным средствам отладчика.

    Рис. 22.10. Кнопки панели Отладка

    Команда Назначение
    Compile Компиляция программы
    Run Sub/UserForm Запуск процедуры или формы
    Break Прерывание выполнения программы +
    Reset Остановка выполнения программы
    Toggle Breakpoints Установить точку останова
    Clear All Breakpoints Снять все точки останова
    Step Into Шаг с заходом во вспомогательные процедуры
    Step Over Шаг с обходом вспомогательных процедур
    Step Out Шаг с выходом из вспомогательной процедуры
    Step to Cursor Шаг до курсора. Запускает программу на выполнение до строки с курсором
    Set Next Statement Позволяет устанавливать следующий выполняемый оператор
    Show Next Statement Показывает следующий выполняемый оператор
    Immediate Window Отображает окно отладочных результатов вычисления
    Locals Window Отображает окно локальных переменных процедуры
    Watch Window Отображает окно контрольных выражений программы
    Add Watch Добавляет выражение в окно Watch
    Edit Watch Исправляет выражение в окне Watch
    Quick Watch Просматривает значение выделенного выражения
    Call Stack Позволяет показать стек вызовов процедур в текущий момент. Эта кнопка очень полезна при работе с рекурсивными процедурами
    Comment Block Позволяет закомментировать выделенный блок операторов
    Uncomment Block Отменяет сделанные комментарии
    Toggle Bookmarks Устанавливает закладку
    Clear All Bookmarks Снимает все установленные закладки
    Find Вызывает диалоговое" окно поиска, посредством которого можно найти ту или иную переменную, выражение и т. д.

    Таблица 22.1. Средства отладчика

    К сожалению, не все приемы отладки можно рассмотреть на нашем простейшем примере.