$DebugInfo — Директива компилятора Delphi

Директивы Компилятора-Версии Delphi

у меня есть единица, которую я написал в Delphi 7 некоторое время назад, и только что получил удовольствие (боль) от преобразования в Delphi XE (Unicode).

устройство отлично работает после некоторых проблем, теперь я пытаюсь сделать это устройство совместимым с различными версиями Delphi, если мне когда-либо понадобится переключить IDE обратно на Delphi 7 при обновлении другого кода.

У меня есть только Delphi 7 и Delphi XE, но из того, что я собираю код, написанный на Delphi 1 в Delphi 2007, будет компилироваться, но код из Delphi 2009 и выше будет Unicode.

. Во всяком случае, в блоке я разделяю не-unicode и unicode следующим образом:

Как изменить директиву компилятора, чтобы правила применялись к нескольким версиям? Например что-то вроде:

это будет охватывать все версии Delphi, если я распространю источник или .блок УЗК.

2 ответов

интересно, Самый простой подход в этом случае-переключить поведение на UNICODE условное. Это условие определяется тогда и только тогда, когда вы используете версию Delphi в Юникоде, т. е. в Delphi 2009 и более поздних версиях. Большим преимуществом этого является то, что это будущее-вам не нужно обновлять код каждый раз, когда выходит новый Делфи. Более того, условный переключатель будет гораздо более читаемым, поскольку он будет четко выражать намерение.

Delphi документация имеет отличный темы список всех предопределенных условий. Полный список условий версии также связан оттуда.

Опции компилятора задаваемые в настройках

Кроме Debug Information не нужно ничего снимать.

Программа представляет собой набор машинных команд. Текст программы представляет собой текстовый файл. Вопрос: как отладчик узнаёт, когда надо остановиться, если вы поставили бряк на строку в тексте? Где же соответствие между текстовым файлом и набором байт в exe-файле? Вот для такой связи и служит отладочная информация. Это, грубо говоря, набор инструкций типа: «машинные коды с 1056 по 1059 относятся к строке 234 модуля Unit1.pas». Вот с помощью такой информации и работает отладчик. По-умолчанию она включена. Делается это в опциях проекта на вкладке «Compiler» в разделе «Debugging». Обычно они все (или почти все) включены для отладочной версии программы и отключаются для конечной версии, которую вы будете распространять. Напомним, что после переключения любой из этих опций необходимо делать полный Build проекта, чтобы опция вступила в силу. «Debug information» (директива <$D+>или <$D->) – это собственно и есть отладочная информация. Т.е. соответствие между текстом программы и её машинным кодом. Вы должны включить эту опцию, если хотите ставить бряки и выполнять пошаговую отладку. Отладочная информация сохраняется вместе с кодом модуля в dcu-файле. Т.е. один и тот же Unit1.dcu может быть скомпилирован как с отладочной информацией, так и без неё. Отладочная информация увеличивает время компиляции, размер dcu-файлов, но не влияет на размер и скорость работы полученного exe-файла (т.е. отладочная информация не подключается к exe-файлу). «Local symbols» (директива <$L+>или <$L->) – является дополнением к отладочной информации. Она отвечает за соответствие между данными в exe-файле и именами переменных. Если вы включаете эту опцию, то отладчик позволит вам просматривать и изменять переменные. Также окно «Call Stack» будет способно отражать переданные в процедуры параметры.«Reference info» – это дополнительная информация для редактора кода, которая позволяет ему отображать более подробную информацию об идентификаторах. Например, где была объявлена переменная.«Use Debug DCUs» — эта опция переключает сборку вашей программы с отладочными модулями Delphi или с обычными. Если вы внимательно посмотрите на установку Delphi, то увидите, что pas файлы из папки Source никогда не используются для компиляции — а только для отладки. Для компиляции же используются уже готовые dcu-файлы из папки Lib. Это уменьшает время компиляции. Поскольку dcu могут быть скомпилированы с отладочной информацией и без неё, то в папке Lib есть два набора dcu-файлов: обычные и отладочные. Переключая эту опцию, вы указываете, какие из них использовать. Если вы выключите эту опцию, то не сможете заходить по F7 в стандартные функции и методы Delphi (т.к. для них будет отсутствовать отладочная информация).

а вот в релизном проекте, зачем нам нужны эти опции

F1:ЦитатаПрограмма представляет собой набор машинных команд. Текст программы представляет собой текстовый файл. Вопрос: как отладчик узнаёт, когда надо остановиться, если вы поставили бряк на строку в тексте? Где же соответствие между текстовым файлом и набором байт в exe-

Директивы по версиям компилятора Delphi: <$ IFDEF VER180>— 2020

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

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

Предположим, вы пишете свой собственный (коммерческий) пользовательский компонент. Пользователи вашего компонента могут иметь разные версии Delphi, чем у вас.

Если они попытаются перекомпилировать код компонента (ваш код) — у них могут быть проблемы! Что если вы использовали параметры по умолчанию в ваших функциях, а у пользователя Delphi 3?

Директива компилятора: $ IfDef

Директивы компилятора — это специальные синтаксические комментарии, которые мы можем использовать для управления функциями компилятора Delphi. Компилятор Delphi имеет три типа директив: переключение директив, директивы параметров а также условные директивы, Условная компиляция позволяет нам выборочно компилировать части исходного кода в зависимости от того, какие условия установлены.

Директива компилятора $ IfDef запускает секцию условной компиляции.

Синтаксис выглядит так:

DefName представляет так называемый условный символ. Delphi определяет несколько стандартных условных символов. В приведенном выше «коде», если определено DefName, код выше $ Else компилируется.

Delphi Version Symbols

Распространенным применением директивы $ IfDef является тестирование версии компилятора Delphi.

В следующем списке указаны символы, которые необходимо проверить при условной компиляции для конкретной версии компилятора Delphi:

  • УСЛОВНОЕ ОБОЗНАЧЕНИЕ — Компиляционная версия
  • VER80 — Delphi 1
  • VER90 — Delphi 2
  • VER100 — Delphi 3
  • VER120 — Delphi 4
  • VER130 — Delphi 5
  • VER140 — Delphi 6
  • VER150 — Delphi 7
  • VER160 — Delphi 8
  • VER170 — Delphi 2005
  • VER180 — Delphi 2006
  • VER180 — Delphi 2007
  • VER185 — Delphi 2007
  • VER200 — Delphi 2009
  • VER210 — Delphi 2010
  • VER220 — Delphi XE
  • VER230 — Delphi XE2
  • WIN32 — Указывает, что операционной средой является Win32 API.
  • LINUX — Указывает, что операционной средой является Linux
  • MSWindows — Указывает, что операционной средой является MS Windows / li]
  • ПРИСТАВКА — Указывает, что приложение компилируется как консольное приложение.

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

Примечание: символ VER185, например, используется для обозначения компилятора Delphi 2007 или более ранней версии.

Использование символов «VER»

Обычно (и желательно) для каждой новой версии Delphi добавлять несколько новых подпрограмм RTL к языку.

Например, функция IncludeTrailingBackslash, представленная в Delphi 5, добавляет «» в конец строки, если ее там еще нет. В проекте Delphi MP3 я использовал эту функцию, и несколько читателей пожаловались, что не могут скомпилировать проект — у них есть какая-то версия Delphi до Delphi 5.

Одним из способов решения этой проблемы является создание собственной версии этой подпрограммы — функции AddLastBackSlash.

Если проект должен быть скомпилирован на Delphi 5, вызывается IncludeTrailingBackslash. Если используются некоторые из предыдущих версий Delphi, мы моделируем функцию IncludeTrailingBackslash.

Это может выглядеть примерно так:

функция AddLastBackSlash (ул: строка) : строка; начать Результат: = IncludeTrailingBackslash (str); если Copy (str, Length (str), 1) = «» затем Результат: = ул еще Результат: = str + «»; конец;

При вызове функции AddLastBackSlash Delphi выясняет, какая часть функции должна использоваться, а другая часть просто пропускается.

Delphi 2008?

Delphi 2007 использует VER180 для обеспечения неразрывной совместимости с Delphi 2006, а затем добавляет VER185 для разработки, которая по каким-либо причинам должна быть нацелена на Delphi 2007.

Примечание. Каждый раз, когда интерфейс модуля изменяет код, использующий этот модуль, его необходимо перекомпилировать.Delphi 2007 — выпуск без прерываний, означающий, что файлы DCU из Delphi 2006 будут работать как есть.

$DebugInfo — Директива компилятора Delphi

<$I+>и <$I->— директивы контроля ввода/вывода <$M>и <$S>— директивы, определяющие размер стека <$M+>и <$M->— директивы информации времени выполнения о типах <$Q+>и <$Q->— директивы проверки переполнения целочисленных операций <$R>— директива связывания ресурсов <$R+>и <$R->— директивы проверки диапазона <$APPTYPE CONSOLE>— директива создания консольного приложения 1) Директивы компилятора, разрешающие или запрещающие проверку утверждений. По умолчанию <$C+>или <$ASSERTIONS ON>Область действия локальная Директивы компилятора $C разрешают или запрещают проверку утверждений. Они влияют на работу процедуры Assert,используемой при отладке программ. По умолчанию действует директива <$C+>и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно. Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву <$C->.

Условная компиляция в Delphi

Условная компиляция в Delphi, по сути, очень полезная и удобная возможность, которая позволяет Delphi компилировать или не компилировать код в зависимости от определенных символов условной компиляции. Говоря более простым языком (возможно и не совсем корректно), условная компиляция позволяет убрать или, наоборот, добавить часть кода исполняемого файла. Так или иначе, любой Delphi разработчик встречается с символами условной компиляции как минимум один раз за время работы над проектом.

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

Для начала, рассмотрим очень простой код, который вы можете повторить в Delphi за несколько секунд:

Теперь нажмите F9 и проверьте, что написано в отладчике в «Events»:

Разберемся с тем, что мы только что написали.

$IFDEF — это директива компилятора;

DEBUG — условное определение или символ условной компиляции. Символ обязательно должен начинаться с буквы за которой может следовать любое количество букв, цифр и знаков подчеркивания, однако использоваться будут лишь первые 255 символов.

Процедура отправляет строку в отладчик для отображения.

Завершает условную компиляцию, инициированную последней директивой <$IFxxx>(почему не <$IFDEF>— смотрим далее).

Таким образом, используя директивы и мы указали компилятору дословно следующее: если где-либо по ходу компиляции был встречено условное определение DEBUG, то надо выполнить OutputDebugString.

Где определено условное определение DEBUG? Конкретно в этом случае, символ DEBUG можно найти, если зайти в настройки проекта: Project -> Options ->Delphi Compiler :

Здесь же можно определить и свои собственные символы. Давайте, например, добавим свой символ условной компиляции TEST. Для этого открываем диалоговое окно редактирования символов условной компиляции (жмем кнопку «…» в строке «Conditional defines») и заносим наш символ в список:

Теперь изменим наш код, приведенный в начале статьи, чтобы он работал с нашим символом условной компиляции:

Теперь можете снова запустить приложения в режиме отладки и посмотреть, что в Events появится строка «TEST IS ON».

Сейчас мы с вами рассмотрели самый простой способ использования условной компиляции в Delphi — использование директив и , а также определение собственного символа условной компиляции через свойства проекта. Вместе с этим, определить (включить) свой символ условной компиляции можно и в коде программы. Для этого используется директива компилятора . Воспользуемся этой директивой:

Соответственно, если есть директива определения нового символа, то должна быть и директива, которая отключает символы условной компиляции — она называется . Можете написать, например, вот такой код:

и убедиться, что символ DEBUG выключен, а в окне Events не появится строка «debug is on».

Двигаемся далее. Что делать, если нам необходимо вывести строку не когда символ включен, а именно тогда, когда он выключен? Здесь, опять же, есть варианты. Короткий вариант — воспользоваться директивой противоположной — она называется и код между и выполняется, если символ выключен:

Второй вариант — использование директивы , если в зависимости от состояния символа условной компиляции вам надо выполнять различные участки кода:

Соответственно, нет необходимости далее повторять этот же участок кода с использованием — работать будет, но прямо противоположно.

Также следует обратить внимание на то, что все условные символы оцениваются в Delphi, когда вы выполняете Build проекта. Справка Delphi рекомендует для надежности пользоваться командой Project -> Build All Projects, чтобы быть уверенным, что все символы условной компиляции определены верно.

В Delphi также определен набор символов условной компиляции, которые вы можете использовать при работе над своим проектом.

Например, символ условной компиляции VER330 определен для Delphi 10.3 Rio и с его помощью можно определить какой код должен или не должен выполняться, в случае, если версия компилятора Delphi — 33. Например, воспользуемся фичей Delphi 10.3 Rio под названием Inline Variable Declaration:

Сразу может возникнуть вопрос: как сделать так, чтобы приведенный выше код сработал не только в Delphi 10.3 Rio, но и в последующих версиях?
Это можно сделать воспользовавшись, например, такой конструкцией:

Здесь мы уже воспользовались директивой с помощью которой проверили значение константы CompilerVersion, которая находится в модуле System.

Здесь же стоит обратить внимание и на окончание блока — мы использовали директиву , как того требовала Delphi до версии Delphi XE4:

  • для директивы $IFDEF должна быть определена директива $ENDIF
  • для директивы $IF должна быть определена директива $IFEND

В XE4 нам разрешили использовать для закрытия блоков <$IF>, и . Однако, если у вас возникают проблемы при использовании связки и , то вы можете использовать специальную директиву , чтобы потребовать использовать для именно <$IFEND>:

Теперь, если в коде выше использовать директиву $ENDIF, то получим сообщение об ошибке:

Директиву , кстати, можно использовать и с другими константами проекта, например, так:

Так как наша константа Version содержит значение 2, то выполнится участок кода расположенный после . Можете сменить значение константы Version на 1, чтобы убедиться, что выполнится участок кода, где определена переменная s.

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

  1. Использование условной компиляции позволяет нам выполнять тот или иной код, в зависимости от того, какие константы и символы условной компиляции определены или не определены в проекте.
  2. Используя предопредленные символы условной компиляции можно указывать Delphi какой код необходимо выполнить, например, если программа собирается под Android, или, если поддерживается архитектура x64 и т.д.
  3. Директива $IF может использоваться с различными константами, в том числе и определенными самим разработчиком.

При подготовке статьи использовалась следующая информация официальной справки по Delphi:

$DebugInfo — Директива компилятора Delphi

Давным-давно, когда компьютеры были большими, а именно — лет двадцать назад, отладка заключалась в копании в огромных кипах бумаги с исходными текстами и распечатках результатов работы и потреблении невероятного количества кофеина, а зачастую и анальгина. Современный программист, особенно если он программирует на Delphi, больше не чернорабочий от программирования с крепкими от переворачивания центнеров бумаги мускулами, а «белый воротничок», окруженный разнообразными »электронными мухобойками», предоставляемыми Delphi.
Интегрированный отладчик Delphi переполнен полезными, не очень полезными и совсем бесполезными возможностями, и кажется, что изучить их просто невозможно. Однако использование отладчика D elphi просто, как апельсин: ведь когда вы компилируете свою программу и запускаете ее из среды Delphi, вы уже пользуетесь встроенным отладчиком, хотя, вероятно, и не подозреваете об этом. Как всегда, 90% проблем решается 10% возможностей программного обеспечения, а потому все разнообразие работы с отладчиком вы можете изучить позднее, при решении оставшихся 10% ваших проблем.

Настройка IDE для отладки
Для работы со встроенным отладчиком Delphi 4 его интегрированная среда разработки (IDE) предлагает целую серию установок, большинство из которых вам лучше не трогать, а оставить, как есть (по умолчанию). Однако если вы все-таки решили изменить установки, выберите команду Tools/Options и в появившемся диалоговом окне Environment Options щелкните на вкладке Preferences (она показана на рис 2.5)
Ниже перечислены опции вкладки Preferences и их функции.

  • Integrated Debugging. Позволяет включать и отключать встроенный отладчик. Если вы отключите отладчик, отладочные команды в меню Run станут недоступными.
    Совет: Если у вас возникли проблемы при запуске приложения из интегрированной среды, возможно, это вызвано конфликтом встроенного отладчика с другими приложениями, запущенными в системе. Попробуйте отключить встроенный отладчик и, если это поможет, будьте уверены — проблема кроется в одном из уже запущенных в системе приложений. Лучшим решением будет перезагрузка и последующий запуск только абсолютно необходимых приложений.
    Рис. 2.5. Использование вкладки Preferences для настройки интегрированного отладчика Delphi.

  • Step Program Block. Эта опция определяет, должен ли отладчик останавливаться перед началом выполнения основного блока begin. . . end при трассировке программы. Обычно данная опция отключена, и включать ее имеет смысл при добавлении кода в основной блок программы либо при отладке консольного приложения.
  • Hide Designers on Run. Когда эта опция включена, окно Object Inspector и формы, использующиеся при разработке приложения, перед запуском программы на выполнение закрываются. Отключение опции позволяет запускать программу быстрее, но эффект перекрывается используемыми незакрытыми ресурсами приложения. Впрочем, будет ли выбрана эта опция, зависит от пользователя.
  • Break on Exception. При включенной опции IDE всегда перехватывает исключительные ситуации и выводит окно сообщения, даже если в программе исключительная ситуация обрабатывается блоком try. . .except. Включение этой опции упростит отладку, так как выводимые сообщения при этом будут более информативными, чем сообщения обработчика, установленные по умолчанию (сравните рис. 2.6 и 2.7). Помимо этого, IDE размещает окно редактора поверх остальных и выделяет строку, вызвавшую исключительную ситуацию.

Рис. 2.6. Сообщение об исключительной ситуации при включенной опции Break on Exception Рис. 2.7. Сообщение об исключительной ситуации, выводимое обработчиком по умолчанию

Совет: Конечно, опция Break on Exception полезна, но может привести в растерянность новичка в Delphi, особенно когда сообщается об исключительной ситуации, которую должен обработать блок try. . .except. Вы можете либо отключить эту опцию, либо запустить приложение не из среды Delphi, чтобы увидеть его работу глазами конечного пользователя.

Minimize on Run Опция сворачивает окно IDE при запуске приложения Подобно опции Hide Designers on Run, ее установка зависит исключительно от личных предпочтений программиста На странице Display диалогового окна Environment Options есть еще одна установка— опция Visible Gutter. Она включает или отключает отображение серой вертикальной полосы, расположенной слева от окна редактирования (рис. 2.8), на которой мнемоническими значками отображается отладочная информация

Включение в код отладочной информации
Перед началом отладки следует убедиться, что в приложение включена отладочная информация Delphi.
Для компиляции проекта с отладочной информацией следует выполнить команду Project/Options и в диалоговом окне Project Options выбрать вкладку Compiler (рис. 2.9).
Рис. 2.8. Окно редактора с отладочными значками Рис. 2.9 Вкладка Compiler диалогового окна Project Options

Включение отладочной информации регулируется следующими установками

  • Debug Information. Опция контролирует включение отладочной информации. При отключении этой опции вы не сможете трассировать код или ставить точки прерывания в любом модуле. Опция эквивалентна директивам компилятора $D и $DEBUGINFO
  • Local Symb ols. Опция контролирует включение информации о локальных переменных, декларированных, например, внутри функций, процедур и раздела implementation. Вряд ли у вас возникнет необходимость в отключении этой опции, тем более что она игнорируется при выключенной предыдущей опции . Эквивалентные директивы компилятора— $L и $LOCALSYMBOLS.
  • Symbol Info. Эту опцию нельзя целиком отнести к разряду отладочных, так как ее действие направлено на броузер объектов, а не на встроенный отладчик. Если опция включена, броузер объектов сможет выводить информацию для объектов, определенных в модулях Опция игнорируется при выключенных предыдущих двух опциях Эквивалентные директивы компилятора — $Y и $REFERENCEINFO

Обычно вы будете включать опции Debug Information и Local Symbols для пошаговой трассировки приложения. Однако, как упоминалось ранее, вы можете отключить отладочную информацию для некоторых модулей (просто используйте соответствующую директиву в начале модуля).

Использование директивы $D- автоматически отключает опции Local Symbols и Symbol Info, так что вам не надо отключать их отдельно.

Совет: Если вы распространяете модули Delphi в виде DCU-файлов (например, VCL) и не распространяете их исходных текстов позаботьтесь о том, чтобы в скомпилированных модулях не содержалась отладочная информация

Пошаговая отладка
Одна из самых распространенных задач отладки — выполнение программы шаг за шагом, по одной строке за раз для проверки правильности выполнения. При пошаговом прохождении кода отладчик выводит окно редактирования с выполняемой программой. Точка выполнения, показывающая следующую выполняемую строку программы, представляется в виде зеленой стрелки, расположенной слева от области исходного текста в окне редактирования.
После успешной компиляции модуля на полосе отладочной информации каждая строка кода, внесшая свой вклад в модуль, будет отмечена маленьким, синим кружком. Если же строка не помечена, значит, здесь поработал оптимизатор. Поскольку для таких строк выполняемый код не сгенерирован эти строки не будут помечены точкой выполнения.
Интегрированная среда Delphi предоставляет пользователю несколько команд пошаговой отладки доступных в меню Run (рис 2.10)
Рис 2.10 Используйте меню Run для выполнения команд отладки

Ниже перечислены команды отладки.

  • Run. Выбор этой команды запускает приложение на выполнение в обычном режиме. Вы можете использовать ее как для запуска приложения, так и для продолжения его работы после какого-либо прерывания выполнения (например, по точке останова). Если включена опция Break on Exception, используйте команду для продолжения работы после получения сообщения об исключительной ситуации
  • Step Over. Когда точка выполнения находится на строке содержащей вызов процедуры или функции, используйте эту команду для выполнения строки, включая вызовы в один шаг, без прохождения отдельных строк вызываемых функций. Точка выполнения перемещается при выполнении на следующую строку
  • Trace Into. В отличие от предыдущей команды, эта опция отработает пошаговую отладку вызываемых процедур и функций. Другими словами, если, например, в строке вызывается некая процедура, то при выполнении этой команды точка выполнения перейдет на первую строку процедуры. Однако если в строке нет таких вызовов, значит, последние две команды идентичны. Будьте осторожны при пошаговой трассировке обработчика события OnPaint. Поскольку при пошаговой отладке окно редактора размещается поверх других окон, требуется перерисовка окна приложения, для чего вызывается обработчик события OnPaint. Вы попадаете в замкнутый круг, точнее— в бесконечный цикл вызовов одного и того же обработчика. Тем не менее, стоит лишь проследить, чтобы окна приложения и редактора не перекрывались, и проблема разрешится сама собой.
  • Trace to Next Source Line. Иногда ваш код вызывает другой код косвенно, например, при вызове функции, которая запускает обработчик события, или при вызове функции Windows API, которая, в свою очередь, запускает функцию косвенного вызова. Поскольку такие вызовы косвенные, отладчик не видит вызова и не отслеживает пошагового выполнения таких вызовов . Однако использование описываемой команды приводит к отслеживанию таких вызовов и останову отладчика на первой строке вызываемой таким образом функции или процедуры.
  • I Run to Cursor. Зачастую вам вовсе не хочется в поисках ошибки, местоположение которой с какой-то точностью вам известно, пошагово добираться до нужного места через сотни, а то и тысячи строк кода. В таком случае просто поместите курсор на нужную вам строку программы в окне редактирования и используйте команду Run to Cursor. Эти действия эквивалентны временному помещению точки останова в необходимую вам строку программы, и после выполнения предшествующего строке кода работа программы приостанавливается. Если вы пытаетесь выполнить программу до позиции курсора, который находится в строке, не содержащей отладочной информации, вы получите сообщение об ошибке, показанное на рис. 2.11.

Рис. 2.11. Это сообщение о том, что вы пытаетесь остановить выполнение программа на строке, не содержащей отладочной информации.

  • Show Execution Point. Эта команда заставляет среду разработки открыть окно редактора и показать выполняемую в настоящее время строку программы. Она полезна в случаях, когда вы, например, закрыли или свернули окно редактора во время отладки (обычно при нормальном состоянии окна отладчик делает это автоматически).
  • Program Pause. Выбор этой команды немедленно останавливает выполнение программы. Она особенно полезна при зацикливании программы.
  • Program Reset. Если вы достаточно «наотлаживались» и хотите завершить работу своей программы или запустить ее заново, используйте эту команду. Она немедленно прекратит выполнение программы и вернет вас в среду разработчика.

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

Просмотр значений переменных
При пошаговом прохождении программы в отладчике вы, несомненно, захотите узнать, что содержится в различных переменных. Для этого можете использовать окно просмотра переменных Watch List, которое предоставляет возможность пассивно просматривать содержимое одной или нескольких переменных, или диалоговое окно Evaluate/Modify, позволяющее работать только с одной переменной (в нем можно не только просмотреть, но и изменить ее содержимое).
Для просмотра значения переменной используйте команду Run/AddWatch или установите указатель мыши на переменную в окне редактирования, щелкните правой кнопкой мыши и выберите из контекстного меню команду Add Watch at Cursor. После этого появится диалоговое окно Watch Properties, показанное на рис. 2.12. Введите имя переменной в поле Expression (если оно не появилось там автоматически). Обратите внимание на то, что вы можете просматривать значения не только переменных, но и выражений типа х*(y+z). Единственное ограничение— выражение не может содержать вызовов функций, поскольку это может вызвать побочный эффект, связанный с незапланированным вызовом функции, описанный выше, в подразделе »Использование директивы Assert». Допускается также просмотр значений записей, массивов и других структурированных элементов.
Поле Repeat Count используется в том случае, если у вас есть большой массив, и вы хотите просмотреть его часть. Предположим, что вам надо знать значения элементов 826-833 следующего массива

var
BigArray: array[1..1000] of Integer;

Вы не можете просмотреть массив BigArray, так как 1 000 элементов просто не поместятся в окне (да и пролистать ненужные вам 825 элементов — работенка немалая!) Вместо этого вы просите показать вам значение BigArray [826] и устанавливаете параметр Repeat Count равным 8. При этом вам будут показаны значения восьми элементов массива— от 826 по 833.
Использование поля Digits позволяет определить количество значащих цифр при выводе числа с плавающей точкой.
Отключенная опция Enabled предотвращает вывод значения переменной, однако , среда будет хранить все параметры, заданные для ее просмотра. Так, вы можете временно убрать с экрана информацию о переменной, которая в настоящий момент вам не нужна, и быстро восстановить ее на экране при необходимости без повторного ввода характеристик просмотра.
В диалоговом окне имеется также набор переключателей для выбора способа представления переменной. Значение Default позволяет среде разобраться с типом переменной самостоятельно. Как правило, такое решение оптимально, однако в любой момент вы можете представить переменную как переменную того типа, который вас интересует. Опция Memory dump представляет информацию как набор байтов, что бывает полезно, когда необходимо увидеть внутреннее представление информации в переменной.
На рис 2.13 отображены значения нескольких переменных в окне Watch List. Кроме того, в некоторых случаях отладчик выводит информацию о причинах, по которым содержимое переменной недоступно.
Рис. 2.12. Использование диалогового окна Watch Properties для добавления или изменения набора переменных в окне просмотра. Рис. 2.13. Просмотр переменных.

Смысл приведенных сообщений поясняется ниже

  • Variable ‘X’ inaccessible here due to optimization(Переменная ‘X’ недоступна из-за оптимизации). В этой точке значение переменной просмотреть невозможно (иногда это можно сделать в другом месте программы), так как для нее не выделена память из-за оптимизации программы компилятором.
  • Symbol was eliminated by linker (Переменная удалена компоновщиком). Переменная удалена из кода программы компоновщиком, так как на нее нет ни одной ссылки в тексте программы.

Отладчик также выводит сообщение об ошибке, если имя переменной написано неправильно, например вы запросили значение Foo [5], в то время как переменная Foo массивом не является.

Совет: Когда вы пытаетесь просмотреть свойства объекта, выводимые значения могут оказаться бессмысленными. Многие свойства объектов, выглядящие как переменные, на самом деле являются вызовами функций. Отладчик не вызывает функции для определения значений, а потому корректные значения при таком просмотре вы получить не можете. Выход — в объявлении новых переменных, присвоении им значений свойств и просмотре не свойств, а новых переменных. Неприятности могут начаться из-за слишком умного оптимизатора, который сообразит, что, раз в программе значение переменной больше не используется, ее можно выбросить без ущерба для программы (увы, но не для отладки программы!) Если это происходит, используйте глобальные переменные, т.е. переменные, объявленные вне функции или процедуры. Отладчик всегда корректно отобразит значения глобальных переменных.

Диалоговое окно Evaluate/Modify
Для вывода диалогового окна Evaluate/Modify выберите команду Run/Evaluate/Modify (рис 2.14). Другой способ вызова диалогового окна — установить курсор в окне редактирования на необходимой вам переменной, щелкнуть правой кнопкой мыши и в контекстном меню выбрать команду Evaluate/Modify.
Введите выражение в поле Expression так же, как в диалоговом окне Watch Properties (см рис 2.12). Затем щелкните на кнопке Evaluate для того, чтобы увидеть результат в поле Result. Если выражение состоит только из имени простой переменной (не массива или структуры!), можете ввести новое значение для переменной в поле New Value и, щелкнув на кнопке Modify, присвоить переменной новое значение. Это позволяет корректировать значения переменных в процессе отладки, не останавливаясь и не перекомпилируя всю программу, что сбережет ваше время и нервы, и даст возможность, найдя одну ошибку, искать другие, а исправлением первой ошибки заняться чуть позже.
Рис 2.14 Использование диалогового окна Evaluate/Modify для проверки изменения отдельной переменной.

Диалоговое окно Evaluate/Modify — немодальное, т. е. вы можете не закрывать его, продолжая отладку. Однако учтите, что в отличие от окна Watch List диалоговое окно Evaluate/Modify не отслеживает изменения значений переменных и для получения информации о текущем состоянии переменной вам необходимо воспользоваться кнопкой Evaluate.
Так же, как и окно Watch List, диалоговое окно Evaluate/Modify может выводить сообщения об ошибках, если отладчик не в состоянии вывести информацию о переменных. И точно так же не выводится информация о выражениях, содержащих вызов функций.
Как видите, окно Watch List и диалоговое окно Evaluate/Modify очень похожи, но каждое из них имеет свои преимущества в различных ситуациях. Обратите внимание на одно существенное отличие диалогового окна Evaluate/Modify его вывод выполняется в поле с несколькими строками, а потому оно более удобно для просмотра структур и объектов.

Установка точек останова
Точка останова (breakpoint) — своеобразный знак STOP для отладчика (на полосе слева в окне редактора она и выглядит как маленький красный значок). Когда ваше приложение запущено под отладчиком и доходит до строки, в которой находится точка останова, оно прекращает работу и ждет ваших дальнейших распоряжений. Такие точки могут быть условными и безусловными. Отладчик всегда останавливается на точке безусловного останова и может останавливаться в точке условного останова, когда выполнено условие. Интегрированный отладчик Delphi поддерживает два типа условий — логическое и по количеству проходов. Ниже рассмотрены оба типа.
Установить точки останова можно следующими способами:

  • Поместите курсор редактирования на выбранную строку программы и нажмите клавишу команды Toggle Breakpoint (по умолчанию это клавиша > ) для установки или удаления точки останова в этой строке. То же самое можно выполнить и с помощью контекстного меню.
  • Выберите команду Run/Add Breakpoint, и откроется диалоговое окно Edit breakpoint (рис 2.15). Для установки простейшей точки останова просто щелкните на кнопке New. Вы также можете использовать поля Filename и Line Number для установки точек останова в другом файле или строке за пределами текущей позиции курсора. Поля Condition и Pass count используются для установки точки условного останова.

После установки одной или нескольких точек останова можете использовать окно Breakpoint List для управления ими. Для вызова окна Breakpoint List выберите команду View/Breakpoints (рис. 2.16). В этом окне можете щелкнуть на строке конкретной точки правой кнопкой мыши и в контекстном меню отключить точку останова с помощью команды Disable (вновь включить точку останова можно с помощью команды Enable) или удалить ее с помощью команды Delete. Команды View Source и Edit Source активизируют окно с текущим файлом исходного текста, при этом команда Edit Source устанавливает курсор в строку с точкой останова. Команда Properties выводит диалоговое окно Edit breakpoint, показанное на рис. 2.15, позволяя тем самым изменять параметры точки останова. Рис. 2.15. Использование диалогового окна Edit breakpoint для установки новой точки останова. Рис. 2.16. Использование окна Breakpoint list для управления точками останова.

После щелчка правой кнопкой мыши в окне при невыбранной точке останова выводится контекстное меню, в котором команда Add служит для добавления новой точки, Delete All удаляет все точки останова, а команды Disable All и Enable All отключают или включают все точки останова в списке.
Для превращения безусловной точки останова в условную, необходимо вызвать диалоговое окно Edit breakpoint (см. рис. 2.15) и ввести условное выражение или количество проходов в соответствующие поля.
Условное выражение, введенное в поле Condition, может быть любым логическим выражением. По достижении точки останова отладчик вычисляет значение выражения и, если результат ложен, продолжает выполнение программы. Если выражение истинно, выполнение программы приостанавливается. Как обычно, выражение не должно использовать вызов функции. Такие точки останова полезны, если вы можете попасть в интересующий вас фрагмент кода различными путями, но вы хотите остановить выполнение программы только при достижении каких-либо конкретных условий.
Ненулевое значение, введенное в поле Pass count, дает отладчику задание продолжать выполнение программы при прохождении через точку останова, пока через нее не будет выполнено соответствующее количество проходов. При каждом проходе через точку останова отладчик уменьшает значение счетчика на единицу и по достижении нулевого значения программа приостанавливается. Такой метод полезен при работе с циклами, особенно если вы знаете, что ошибка происходит после определенного количества циклов.
Сейчас, когда вы изучили основы технологии отладки, вероятно, у вас возникло желание поставить точку останова у себя в голове и поработать с точками останова в программах. Кстати, один из отличных методов понять, как работает та или иная программа, — проследить за ее пошаговым выполнением, а поскольку ни установка точек останова, ни просмотр или изменение переменных не изменяют текста программы, вы можете работать смело, не опасаясь каким-либо образом «поломать» используемое в учебных целях приложение.

Отладка DLL
В предыдущих версиях Delphi для отладки библиотек динамической компоновки требовался внешний отладчик (Turbo Debugger for Windows). Delphi 4 внесла возможность отладки DLL в список своих возможностей. Windows не может загрузить DLL без предварительной загрузки использующего ее ЕХЕ, поэтому вам с начало придется набросать простенькую программку, использующую интересующую вас DLL. В главном меню выберите команду Run/Parameters для вывода диалогового окна Run Parameters. Если текущий проект— DLL (DPR-файл начинается ключевым словом library, а не program), поле Host Application будет доступно, и в нем вам надо либо ввести имя использующей DLL программы, либо выбрать его с помощью кнопки Browse.
После выбора приложения запуск и отладка DLL становятся обычной рутинной работой со всеми возможностями, используемыми при отладке программ, — установкой точек останова, просмотром значений переменных и т.д.
Точно так же вы будете отлаживать и свои компоненты ActiveX, и объекты автоматизации OLE.

Окно CPU (дизассемблер)
Окно CPU предоставляет возможность увидеть работу приложения на уровне языка ассемблера . Те, кто использовали отладчик Turbo Debugger for Windows, должны знать возможности, предоставляемые таким окном. Эффективное его использование предполагает знание ассемблера Intel x86 и архитектуры процессора, так что, если вы не вполне уверенно себя чувствуете, можете пропустить этот раздел.
Окно CPU требуется крайне редко, но если в нем возникла необходимость, значит, это действительно необходимость. Это — ultima ratio, последний довод, и используется он в безвыходных положениях, когда обычная трассировка кода не позволяет найти, понять и исправить ошибки. Только в таких случаях окно CPU и проход по ассемблерным инструкциям может приподнять завесу над причиной возникновения ошибок.
Чтобы использовать окно CPU необходимо его включить (по умолчанию оно отключено). Для этого придется использовать программу RegEdit из поставки Windows 95 (Windows NT). Запустите Reg E dit и пробирайтесь по иерархическому дереву папок. Сначала откройте папку HKEY_CURRENT_USER. Во вложенной ветви зайдите в папку Software, затем — в Borland, Delphi и, наконец, в 4.
Одна из папок называется Debugging. Щелкните на ней и, когда она откроется, появится список пар Имя/Данные в окошке справа. Добавьте новое значение с именем EnableCPU и значением 1.
При следующем запуске Delphi вы увидите новый подпункт меню View/CPU Window.
Для вывода окна выберите View/CPU Window.

Перечислим панели

  • Code pane Панель кода представляет дизассемблированный код в окрестности текущей точки выполнения (если вы не отлаживаете приложение, окно будет полупустым). Кроме того, панель показывает исходный текст строк, соответствующих выполняемому коду. В окне редактирования точка выполнения индицируется маленьким зеленым значком. При пошаговом проходе значок точки выполнения синхронно перемещается по окну CPU и окну редактирования.
  • Register pane. В панели регистров отображается содержимое 16 регистров процессора. Значения регистров, изменившиеся в результате выполнения последней операции, выделены красным цветом.
  • Flags pane. Панель флагов показывает состояние 14 флагов процессора. Установленный флаг представляется значением 1, сброшенный флаг значением 0. В зависимости от процессора некоторые флаги могут быть недоступными.
  • Stack pane. Панель стека показывает содержимое стека приложения. Вы можете изменять представление содержимого стека с помощью контекстного меню.
  • Data pane. По умолчанию в панели данных выводится содержимое глобального сегмента данных приложения. Ее вид можно изменить так же, как и вид панели стека.

Каждая из панелей в окне CPU имеет собственное контекстное меню. Вы можете поэкспериментировать с пунктами меню и получить более полное представление о возможностях манипулирования панелями.

Окно состояния подзадач.
Окна Thread Status, Modules и Call Stack предоставляют дополнительную информацию, которая может быть полезна при отладке приложения.
В окне Thread Status перечислены все активные подзадачи текущего процесса. Для просмотра состояния подзадач выберите команду View/Threads, и на экране появится окно Thread Status (рис 2.17).
Рис 2.17 . Использование окна Thread Status для просмотра атрибутов подзадач в приложении

В четырех колонках окна представлена следующая информация:

  • Thread ID. Уникальный идентификатор подзадачи, присвоенный ей операционной системой.
  • State. Состояние подзадачи, обычно — Running или Stopped. Если ваше приложение запущено, но ожидает ввода от пользователя, состояние выводится как Runnable.
  • Status. Статус подзадачи может иметь одно из четырех значений. Breakpoint означает, что поток остановлен в точке останова. Stepped— подзадача находится в режиме пошагового выполнения. Faulted— остановка подзадачи из-за исключительной ситуации и Unknown — статус неизвестен.
  • Location. В этой колонке выводится строка исходного кода, соответствующего текущей точке выполнения подзадачи. Если отладчик не в состоянии определить строку исходного текста, выводится 32-битовый адрес точки выполнения.

Если вами разработано приложение с несколькими подзадачами, и вы хотите отладить одну из подзадач, можете сделать ее основной с помощью окна Thread Status. Выберите подзадачу, которою вы хотите сделать текущей, и щелкните на ней правой кнопкой мыши. Выберите из контекстного меню команду Make Current. При этом фокус выполнения будет передан выбранной подзадаче, и вы сможете отлаживать ее как основную задачу.
В контекстном меню окна содержатся две команды — View Source и Go to Source. Они могут пригодиться для того, чтобы проследить за точкой выполнения другой подзадачи без передачи ей фокуса.

Окно Modules
В окне Modules отображаются все модели (ЕХЕ-файл вашего приложения и все используемые динамические библиотеки), которые располагаются в адресном пространстве приложения. В него входят непосредственно подключенные DLL и библиотеки, подключенные через другие библиотеки, а также библиотеки, загруженные операционной системой. Чтобы увидеть это окно, изображенное на рис 2.18. выберите команду View/Modules. В окне информация выводится в трех столбцах Name (имя модуля), Address (адрес начала кода модуля) и Path (полный путь каталога, из которого был загружен модуль). Информация о каталоге может быть важна, если возможна загрузка модуля не из того каталога, из которого ожидалась, например, в более старой версии. Информация об адресе обычно используется при отладке в окне CPU.

Окно Call Stack
В этом окне представлен список всех функций и процедур, вызванных к моменту достижения точки выполнения и работа которых приостановлена. Для открытия этого окна, показанного на рис 2.19, используйте команду View/Call Stack. Рис. 2.18. Использование окна Modules для вывода списка модулей, используемых приложением. Рис. 2.19 Использование окна Call Stack для определения всех вызванных функций и процедур.

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

Трассировка исходного кода VCL
Если вы используете соответствующую версию поставки Delphi 4, значит, в нее входят исходные тексты VCL (Visi Component Library). В поставку VCL входят скомпилированными без отладочной информации, что означает, что при отладке вы не сможете пройти код пошагово. Нет особой необходимости трассировать код VCL, но если вы хотите убедиться, что ошибка не в VCL, или посмотреть, как работает функция, придется перекомпилировать модули, которые нужно трассировать, с отладочной информацией.

Совет: Некоторые стандартные модули VCL требуют компиляции с отключенной опцией Overflow Checking для корректной работы. Поэтому при перекомпиляции убедитесь, что эта опция компилятора отключена.

Delphi. Условная компиляция. Краткий справочник

Условная компиляция предназначена для управления компиляцией программного кода. В Delphi имеется несколько способов её реализации, но в основном используются только четыре.

В этой реализации условная директива <$IFDEF …>проверяет, был ли определён указанный в ней символ условной компиляции. Если да, то код программы между директивами <$IFDEF …>и <$ENDIF>компилируется. В противном случае, код между этими двумя директивами компилироваться не будет.

Эта реализация отличается от предыдущей наличием директивы <$ELSE>. В этом случае, если условный оператор определён, будет компилироваться код программы между директивами <$IFDEF>и <$ELSE>. В противном случае, будет компилироваться код программы между директивами <$ELSE>и <$ENDIF>.

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

Как определить символ условной компиляции? Для этого также существует два способа.

Первый – использование директивы

Второй способ. Определить его в свойствах проекта. Для этого в меню Project нужно выбрать пункт Options и в поле Conditional defines ввести символ условной компиляции.

Третий и четвёртый способы являются аналогией первого и второго соответственно. Отличие в том, что используется условная директива <$IFNDEF>. Эта директива проверяет, что указанный символ не определён. То есть, является прямой противоположностью директивы <$IFDEF>.

В случае <$IFNDEF>, код между этой директивой и <$ENDIF>либо <$ELSE>будет скомпилирован, только если указанный в ней символ условной компиляции не определён. В остальном, принцип реализации аналогичен приведённому для директивы <$IFDEF>:

В Delphi уже имеется ряд символов условной компиляции. Вот их «классический» набор.

Значение
MSWINDOWS Код компилируется только в ОС Windows
WIN32 То же самое, только код компилируется лишь для 32-разядной ОС.
LINUX Был введён в Delphi 6 вместе с MSWINDOWS для определения платформы, для которой необходимо компилировать тот или иной код.Так как компиляция для Linux в Delphi до сих пор отсутствует, то использование этого символа в программах не имеет смысла.
CONSOLE Консольное приложение
CPU386 Компиляция для процессоров типа i386 или более современных. Так как речь идёт о процессорах типа i386, использование данного символа уже давно потеряло актуальность.
CONDITIONAL EXPRESSIONS Проверяет использование директив $IF

Также в число «классических» входит и символ VERxxx, который указывает конкретную версию компилятора. По сути, это целое семейство символов условной компиляции, в которое с выходом новой версии Delphi добавляется новый символ соответствующий этой версии. Ниже представлена таблица соответствия версий Delphi символам условной компиляции VERxxx (материал взят с Исходники.ру).

Символ условной компиляции
1 VER80
2 VER90
3 VER100
4 VER120
5 VER130
6 VER140
7 VER150
8 VER160
2005 VER170
2006 VER180
2007* VER180 или VER185
2009 VER200
2010 VER210
XE VER220
XE2 VER230
XE3 VER240
XE4 VER250
XE5 VER260
XE6 VER270
XE7 VER280
XE8 VER290
10 Seatle VER300
10.1 Berlin VER310
10.2 Tokyo VER320

*-версии 2006 и 2007 совместимы между собой на уровне двоичного кода. Поэтому, для поддержки обеих версий следует использовать символ VER180. Если необходима поддержка только версии 2007, необходимо использовать символ VER185.

После выхода в 2011 году кроссплатформенной библиотеки FireMonkey, были введены новые символы условной компиляции для MacOS и iOS. А, в 2013 году с появлением поддержки Android был введён и специальный символ условной компиляции для этой ОС. Ниже представлен перечень этих символов.

Символ условной компиляции
MacOS MACOS
iOS IOS
Android ANDROID

Условная компиляция на примере кроссплатформенного приложения:

Директивы компилятора

директивы условной компиляции

<$C+>и <$C->— директивы проверки утверждений
<$I+>и <$I->— директивы контроля ввода/вывода
<$M>и <$S>— директивы, определяющие размер стека
<$M+>и <$M->— директивы информации времени выполнения о типах
<$Q+>и <$Q->— директивы проверки переполнения целочисленных операций
<$R>— директива связывания ресурсов
<$R+>и <$R->— директивы проверки диапазона
<$APPTYPE CONSOLE>— директива создания консольного приложения

1) Директивы компилятора, разрешающие или запрещающие проверку утверждений

По умолчанию <$C+>или

Область действия локальная

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

директива <$C+>и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно.

Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву <$C->. При этом работа процедур Assert будет блокировано и генерация исключений EassertionFailed производиться не будет.

Директивы действуют на весь файл исходного кода независимо от того, в каком месте файла они расположены.

2) Директивы компилятора, включающие и выключающие контроль файлового ввода-вывода

По умолчанию <$I+>или

Область действия локальная

Директивы компилятора $I включают или выключают автоматический контроль результата вызова процедур ввода-вывода Object Pascal. Если действует директива <$I+>, то при возвращении процедурой ввода-вывода ненулевого значения генерируется исключение EInOutError и в его свойство errorcode заносится код ошибки. Таким образом, при действующей директиве <$I+>операции ввода-вывода располагаются в блоке try. except, имеющем обработчик исключения EInOutError. Если такого блока нет, то обработка производится методом TApplication.HandleException.

Если действует директива <$I->, то исключение не генерируется. В этом случае проверить, была ли ошибка, или ее не было, можно, обратившись к функции IOResult. Эта функция очищает ошибку и возвращает ее код, который затем можно анализировать. Типичное применение директивы <$I->и функции IOResult демонстрирует следующий пример:

В этом примере на время открытия файла отключается проверка ошибок ввода вывода, затем она опять включается, переменной i присваивается значение, возвращаемое функцией IOResult и, если это значение не равно нулю (есть ошибка), то предпринимаются какие-то действия в зависимости от кода ошибки. Подобный стиль программирования был типичен до введения в Object Pascal механизма обработки исключений. Однако сейчас, по-видимому, подобный стиль устарел и применение директив $I потеряло былое значение.

3) Директивы компилятора, определяющие размер стека

Область действия глобальная

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

Если во время работы выясняется, что минимального размера стека не хватает, то размер увеличивается на 4 K, но не более, чем до установленного директивой максимального размера. Если увеличение размера стека невозможно из-за нехватки памяти или из-за достижения его максимальной величины, генерируется исключение EStackOverflow. Минимальный размер стека по умолчанию равен 16384 (16K). Этот размер может изменяться параметром minstacksize директивы <$M>или параметром number директивы <$MINSTACKSIZE>.

Максимальный размер стека по умолчанию равен 1,048,576 (1M). Этот размер может изменяться параметром maxstacksize директивы <$M>или параметром number директивы <$MAXSTACKSIZE number>. Значение минимального размера стека может задаваться целым числом в диапазоне между1024 и 2147483647. Значение максимального размера стека должно быть не менее минимального размера и не более 2147483647. Директивы задания размера стека могут включаться только в программу и не должны использоваться в библиотеках и модулях.

В Delphi 1 имеется процедура компилятора <$S>, осуществляющая переключение контроля переполнения стека. Теперь этот процесс полностью автоматизирован и директива <$S>оставлена только для обратной совместимости.

4) Директивы компилятора, включающие и выключающие генерацию информации времени выполнения о типах (runtime type information — RTTI)

По умолчанию <$M->или

Область действия локальная

Директивы компилятора $I включают или выключают генерацию информации времени выполнения о типах (runtime type information — RTTI). Если класс объявляется в состоянии <$M+>или является производным от класса объявленного в этом состоянии, то компилятор генерирует RTTI о его полях, методах и свойствах, объявленных в разделе published. В противном случае раздел published в классе не допускается. Класс TPersistent, являющийся предшественником большинства классов Delphi и все классов компонентов, объявлен в модуле Classes в состоянии <$M+>. Так что для всех классов, производных от него, заботиться о директиве <$M+>не приходится.

5) Директивы компилятора, включающие и выключающие проверку переполнения при целочисленных операциях

По умолчанию <$Q->или

Область действия локальная

Директивы компилятора $Q включают или выключают проверку переполнения при целочисленных операциях. Под переполнением понимается получение результата, который не может сохраняться в регистре компьютера. При включенной директиве <$Q+>проверяется переполнение при целочисленных операциях +, -, *, Abs, Sqr, Succ, Pred, Inc и Dec. После каждой из этих операций размещается код, осуществляющий соответствующую проверку. Если обнаружено переполнение, то генерируется исключение EIntOverflow. Если это исключение не может быть обработано, выполнение программы завершается.

Директивы $Q проверяют только результат арифметических операций. Обычно они используются совместно с директивами <$R>, проверяющими диапазон значений при присваивании. Директива <$Q+>замедляет выполнение программы и увеличивает ее размер. Поэтому обычно она используется только во время отладки программы. Однако, надо отдавать себе отчет, что отключение этой директивы приведет к появлению ошибочных результатов расчета в случаях, если переполнение действительно произойдет во время выполнении программы. Причем сообщений о подобных ошибках не будет.

6) Директива компилятора, связывающая с выполняемым модулем файлы ресурсов

Область действия локальная

Директива компилятора <$R>указывает файлы ресурсов (.DFM, .RES), которые должны быть включены в выполняемый модуль или в библиотеку. Указанный файл должен быть файлом ресурсов Windows. По умолчанию расширение файлов ресурсов — .RES. В процессе компоновки компилированной программы или библиотеки файлы, указанные в директивах <$R>, копируются в выполняемый модуль. Компоновщик Delphi ищет эти файлы сначала в том каталоге, в котором расположен модуль, содержащий директиву <$R>, а затем в каталогах, указанных при выполнении команды главного меню Project | Options на странице Directories/Conditionals диалогового окна в опции Search path или в опции /R командной строки DCC32.

При генерации кода модуля, содержащего форму, Delphi автоматически включает в файл .pas директиву <$R *.DFM>, обеспечивающую компоновку файлов ресурсов форм. Эту директиву нельзя удалять из текста модуля, так как в противном случае загрузочный модуль не будет создан и сгенерируется исключение EResNotFound.

7) Директивы компилятора, включающие и выключающие проверку диапазона целочисленных значений и индексов

По умолчанию <$R->или

Область действия локальная

Директивы компилятора $R включают или выключают проверку диапазона целочисленных значений и индексов. Если включена директива <$R+>, то все индексы массивов и строк и все присваивания скалярным переменным и переменным с ограниченным диапазоном значений проверяются на соответствие значения допустимому диапазону. Если требования диапазона нарушены или присваиваемое значение слишком велико, генерируется исключение ERangeError. Если оно не может быть перехвачено, выполнение программы завершается.

Проверка диапазона длинных строк типа Long strings не производится. Директива <$R+>замедляет работу приложения и увеличивает его размер. Поэтому она обычно используется только во время отладки.

8) Директива компилятора, связывающая с выполняемым модулем файлы ресурсов

Область действия локальная

Директива компилятора <$R>указывает файлы ресурсов (.DFM, .RES), которые должны быть включены в выполняемый модуль или в библиотеку. Указанный файл должен быть файлом ресурсов Windows. По умолчанию расширение файлов ресурсов — .RES. В процессе компоновки компилированной программы или библиотеки файлы, указанные в директивах <$R>, копируются в выполняемый модуль. Компоновщик Delphi ищет эти файлы сначала в том каталоге, в котором расположен модуль, содержащий директиву <$R>, а затем в каталогах, указанных при выполнении команды главного меню Project | Options на странице Directories/Conditionals диалогового окна в опции Search path или в опции /R командной строки DCC32.

При генерации кода модуля, содержащего форму, Delphi автоматически включает в файл .pas директиву <$R *.DFM>, обеспечивающую компоновку файлов ресурсов форм. Эту директиву нельзя удалять из текста модуля, так как в противном случае загрузочный модуль не будет создан и сгенерируется исключение EResNotFound.

$DebugInfo — Директива компилятора Delphi

Давным-давно, когда компьютеры были большими, а именно — лет двадцать назад, отладка заключалась в копании в огромных кипах бумаги с исходными текстами и распечатках результатов работы и потреблении невероятного количества кофеина, а зачастую и анальгина. Современный программист, особенно если он программирует на Delphi, больше не чернорабочий от программирования с крепкими от переворачивания центнеров бумаги мускулами, а «белый воротничок», окруженный разнообразными »электронными мухобойками», предоставляемыми Delphi.
Интегрированный отладчик Delphi переполнен полезными, не очень полезными и совсем бесполезными возможностями, и кажется, что изучить их просто невозможно. Однако использование отладчика D elphi просто, как апельсин: ведь когда вы компилируете свою программу и запускаете ее из среды Delphi, вы уже пользуетесь встроенным отладчиком, хотя, вероятно, и не подозреваете об этом. Как всегда, 90% проблем решается 10% возможностей программного обеспечения, а потому все разнообразие работы с отладчиком вы можете изучить позднее, при решении оставшихся 10% ваших проблем.

Настройка IDE для отладки
Для работы со встроенным отладчиком Delphi 4 его интегрированная среда разработки (IDE) предлагает целую серию установок, большинство из которых вам лучше не трогать, а оставить, как есть (по умолчанию). Однако если вы все-таки решили изменить установки, выберите команду Tools/Options и в появившемся диалоговом окне Environment Options щелкните на вкладке Preferences (она показана на рис 2.5)
Ниже перечислены опции вкладки Preferences и их функции.

  • Integrated Debugging. Позволяет включать и отключать встроенный отладчик. Если вы отключите отладчик, отладочные команды в меню Run станут недоступными.
    Совет: Если у вас возникли проблемы при запуске приложения из интегрированной среды, возможно, это вызвано конфликтом встроенного отладчика с другими приложениями, запущенными в системе. Попробуйте отключить встроенный отладчик и, если это поможет, будьте уверены — проблема кроется в одном из уже запущенных в системе приложений. Лучшим решением будет перезагрузка и последующий запуск только абсолютно необходимых приложений.
    Рис. 2.5. Использование вкладки Preferences для настройки интегрированного отладчика Delphi.

  • Step Program Block. Эта опция определяет, должен ли отладчик останавливаться перед началом выполнения основного блока begin. . . end при трассировке программы. Обычно данная опция отключена, и включать ее имеет смысл при добавлении кода в основной блок программы либо при отладке консольного приложения.
  • Hide Designers on Run. Когда эта опция включена, окно Object Inspector и формы, использующиеся при разработке приложения, перед запуском программы на выполнение закрываются. Отключение опции позволяет запускать программу быстрее, но эффект перекрывается используемыми незакрытыми ресурсами приложения. Впрочем, будет ли выбрана эта опция, зависит от пользователя.
  • Break on Exception. При включенной опции IDE всегда перехватывает исключительные ситуации и выводит окно сообщения, даже если в программе исключительная ситуация обрабатывается блоком try. . .except. Включение этой опции упростит отладку, так как выводимые сообщения при этом будут более информативными, чем сообщения обработчика, установленные по умолчанию (сравните рис. 2.6 и 2.7). Помимо этого, IDE размещает окно редактора поверх остальных и выделяет строку, вызвавшую исключительную ситуацию.

Рис. 2.6. Сообщение об исключительной ситуации при включенной опции Break on Exception Рис. 2.7. Сообщение об исключительной ситуации, выводимое обработчиком по умолчанию

Совет: Конечно, опция Break on Exception полезна, но может привести в растерянность новичка в Delphi, особенно когда сообщается об исключительной ситуации, которую должен обработать блок try. . .except. Вы можете либо отключить эту опцию, либо запустить приложение не из среды Delphi, чтобы увидеть его работу глазами конечного пользователя.

Minimize on Run Опция сворачивает окно IDE при запуске приложения Подобно опции Hide Designers on Run, ее установка зависит исключительно от личных предпочтений программиста На странице Display диалогового окна Environment Options есть еще одна установка— опция Visible Gutter. Она включает или отключает отображение серой вертикальной полосы, расположенной слева от окна редактирования (рис. 2.8), на которой мнемоническими значками отображается отладочная информация

Включение в код отладочной информации
Перед началом отладки следует убедиться, что в приложение включена отладочная информация Delphi.
Для компиляции проекта с отладочной информацией следует выполнить команду Project/Options и в диалоговом окне Project Options выбрать вкладку Compiler (рис. 2.9).
Рис. 2.8. Окно редактора с отладочными значками Рис. 2.9 Вкладка Compiler диалогового окна Project Options

Включение отладочной информации регулируется следующими установками

  • Debug Information. Опция контролирует включение отладочной информации. При отключении этой опции вы не сможете трассировать код или ставить точки прерывания в любом модуле. Опция эквивалентна директивам компилятора $D и $DEBUGINFO
  • Local Symb ols. Опция контролирует включение информации о локальных переменных, декларированных, например, внутри функций, процедур и раздела implementation. Вряд ли у вас возникнет необходимость в отключении этой опции, тем более что она игнорируется при выключенной предыдущей опции . Эквивалентные директивы компилятора— $L и $LOCALSYMBOLS.
  • Symbol Info. Эту опцию нельзя целиком отнести к разряду отладочных, так как ее действие направлено на броузер объектов, а не на встроенный отладчик. Если опция включена, броузер объектов сможет выводить информацию для объектов, определенных в модулях Опция игнорируется при выключенных предыдущих двух опциях Эквивалентные директивы компилятора — $Y и $REFERENCEINFO

Обычно вы будете включать опции Debug Information и Local Symbols для пошаговой трассировки приложения. Однако, как упоминалось ранее, вы можете отключить отладочную информацию для некоторых модулей (просто используйте соответствующую директиву в начале модуля).

Использование директивы $D- автоматически отключает опции Local Symbols и Symbol Info, так что вам не надо отключать их отдельно.

Совет: Если вы распространяете модули Delphi в виде DCU-файлов (например, VCL) и не распространяете их исходных текстов позаботьтесь о том, чтобы в скомпилированных модулях не содержалась отладочная информация

Пошаговая отладка
Одна из самых распространенных задач отладки — выполнение программы шаг за шагом, по одной строке за раз для проверки правильности выполнения. При пошаговом прохождении кода отладчик выводит окно редактирования с выполняемой программой. Точка выполнения, показывающая следующую выполняемую строку программы, представляется в виде зеленой стрелки, расположенной слева от области исходного текста в окне редактирования.
После успешной компиляции модуля на полосе отладочной информации каждая строка кода, внесшая свой вклад в модуль, будет отмечена маленьким, синим кружком. Если же строка не помечена, значит, здесь поработал оптимизатор. Поскольку для таких строк выполняемый код не сгенерирован эти строки не будут помечены точкой выполнения.
Интегрированная среда Delphi предоставляет пользователю несколько команд пошаговой отладки доступных в меню Run (рис 2.10)
Рис 2.10 Используйте меню Run для выполнения команд отладки

Ниже перечислены команды отладки.

  • Run. Выбор этой команды запускает приложение на выполнение в обычном режиме. Вы можете использовать ее как для запуска приложения, так и для продолжения его работы после какого-либо прерывания выполнения (например, по точке останова). Если включена опция Break on Exception, используйте команду для продолжения работы после получения сообщения об исключительной ситуации
  • Step Over. Когда точка выполнения находится на строке содержащей вызов процедуры или функции, используйте эту команду для выполнения строки, включая вызовы в один шаг, без прохождения отдельных строк вызываемых функций. Точка выполнения перемещается при выполнении на следующую строку
  • Trace Into. В отличие от предыдущей команды, эта опция отработает пошаговую отладку вызываемых процедур и функций. Другими словами, если, например, в строке вызывается некая процедура, то при выполнении этой команды точка выполнения перейдет на первую строку процедуры. Однако если в строке нет таких вызовов, значит, последние две команды идентичны. Будьте осторожны при пошаговой трассировке обработчика события OnPaint. Поскольку при пошаговой отладке окно редактора размещается поверх других окон, требуется перерисовка окна приложения, для чего вызывается обработчик события OnPaint. Вы попадаете в замкнутый круг, точнее— в бесконечный цикл вызовов одного и того же обработчика. Тем не менее, стоит лишь проследить, чтобы окна приложения и редактора не перекрывались, и проблема разрешится сама собой.
  • Trace to Next Source Line. Иногда ваш код вызывает другой код косвенно, например, при вызове функции, которая запускает обработчик события, или при вызове функции Windows API, которая, в свою очередь, запускает функцию косвенного вызова. Поскольку такие вызовы косвенные, отладчик не видит вызова и не отслеживает пошагового выполнения таких вызовов . Однако использование описываемой команды приводит к отслеживанию таких вызовов и останову отладчика на первой строке вызываемой таким образом функции или процедуры.
  • I Run to Cursor. Зачастую вам вовсе не хочется в поисках ошибки, местоположение которой с какой-то точностью вам известно, пошагово добираться до нужного места через сотни, а то и тысячи строк кода. В таком случае просто поместите курсор на нужную вам строку программы в окне редактирования и используйте команду Run to Cursor. Эти действия эквивалентны временному помещению точки останова в необходимую вам строку программы, и после выполнения предшествующего строке кода работа программы приостанавливается. Если вы пытаетесь выполнить программу до позиции курсора, который находится в строке, не содержащей отладочной информации, вы получите сообщение об ошибке, показанное на рис. 2.11.

Рис. 2.11. Это сообщение о том, что вы пытаетесь остановить выполнение программа на строке, не содержащей отладочной информации.

  • Show Execution Point. Эта команда заставляет среду разработки открыть окно редактора и показать выполняемую в настоящее время строку программы. Она полезна в случаях, когда вы, например, закрыли или свернули окно редактора во время отладки (обычно при нормальном состоянии окна отладчик делает это автоматически).
  • Program Pause. Выбор этой команды немедленно останавливает выполнение программы. Она особенно полезна при зацикливании программы.
  • Program Reset. Если вы достаточно «наотлаживались» и хотите завершить работу своей программы или запустить ее заново, используйте эту команду. Она немедленно прекратит выполнение программы и вернет вас в среду разработчика.

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

Просмотр значений переменных
При пошаговом прохождении программы в отладчике вы, несомненно, захотите узнать, что содержится в различных переменных. Для этого можете использовать окно просмотра переменных Watch List, которое предоставляет возможность пассивно просматривать содержимое одной или нескольких переменных, или диалоговое окно Evaluate/Modify, позволяющее работать только с одной переменной (в нем можно не только просмотреть, но и изменить ее содержимое).
Для просмотра значения переменной используйте команду Run/AddWatch или установите указатель мыши на переменную в окне редактирования, щелкните правой кнопкой мыши и выберите из контекстного меню команду Add Watch at Cursor. После этого появится диалоговое окно Watch Properties, показанное на рис. 2.12. Введите имя переменной в поле Expression (если оно не появилось там автоматически). Обратите внимание на то, что вы можете просматривать значения не только переменных, но и выражений типа х*(y+z). Единственное ограничение— выражение не может содержать вызовов функций, поскольку это может вызвать побочный эффект, связанный с незапланированным вызовом функции, описанный выше, в подразделе »Использование директивы Assert». Допускается также просмотр значений записей, массивов и других структурированных элементов.
Поле Repeat Count используется в том случае, если у вас есть большой массив, и вы хотите просмотреть его часть. Предположим, что вам надо знать значения элементов 826-833 следующего массива

var
BigArray: array[1..1000] of Integer;

Вы не можете просмотреть массив BigArray, так как 1 000 элементов просто не поместятся в окне (да и пролистать ненужные вам 825 элементов — работенка немалая!) Вместо этого вы просите показать вам значение BigArray [826] и устанавливаете параметр Repeat Count равным 8. При этом вам будут показаны значения восьми элементов массива— от 826 по 833.
Использование поля Digits позволяет определить количество значащих цифр при выводе числа с плавающей точкой.
Отключенная опция Enabled предотвращает вывод значения переменной, однако , среда будет хранить все параметры, заданные для ее просмотра. Так, вы можете временно убрать с экрана информацию о переменной, которая в настоящий момент вам не нужна, и быстро восстановить ее на экране при необходимости без повторного ввода характеристик просмотра.
В диалоговом окне имеется также набор переключателей для выбора способа представления переменной. Значение Default позволяет среде разобраться с типом переменной самостоятельно. Как правило, такое решение оптимально, однако в любой момент вы можете представить переменную как переменную того типа, который вас интересует. Опция Memory dump представляет информацию как набор байтов, что бывает полезно, когда необходимо увидеть внутреннее представление информации в переменной.
На рис 2.13 отображены значения нескольких переменных в окне Watch List. Кроме того, в некоторых случаях отладчик выводит информацию о причинах, по которым содержимое переменной недоступно.
Рис. 2.12. Использование диалогового окна Watch Properties для добавления или изменения набора переменных в окне просмотра. Рис. 2.13. Просмотр переменных.

Смысл приведенных сообщений поясняется ниже

  • Variable ‘X’ inaccessible here due to optimization(Переменная ‘X’ недоступна из-за оптимизации). В этой точке значение переменной просмотреть невозможно (иногда это можно сделать в другом месте программы), так как для нее не выделена память из-за оптимизации программы компилятором.
  • Symbol was eliminated by linker (Переменная удалена компоновщиком). Переменная удалена из кода программы компоновщиком, так как на нее нет ни одной ссылки в тексте программы.

Отладчик также выводит сообщение об ошибке, если имя переменной написано неправильно, например вы запросили значение Foo [5], в то время как переменная Foo массивом не является.

Совет: Когда вы пытаетесь просмотреть свойства объекта, выводимые значения могут оказаться бессмысленными. Многие свойства объектов, выглядящие как переменные, на самом деле являются вызовами функций. Отладчик не вызывает функции для определения значений, а потому корректные значения при таком просмотре вы получить не можете. Выход — в объявлении новых переменных, присвоении им значений свойств и просмотре не свойств, а новых переменных. Неприятности могут начаться из-за слишком умного оптимизатора, который сообразит, что, раз в программе значение переменной больше не используется, ее можно выбросить без ущерба для программы (увы, но не для отладки программы!) Если это происходит, используйте глобальные переменные, т.е. переменные, объявленные вне функции или процедуры. Отладчик всегда корректно отобразит значения глобальных переменных.

Диалоговое окно Evaluate/Modify
Для вывода диалогового окна Evaluate/Modify выберите команду Run/Evaluate/Modify (рис 2.14). Другой способ вызова диалогового окна — установить курсор в окне редактирования на необходимой вам переменной, щелкнуть правой кнопкой мыши и в контекстном меню выбрать команду Evaluate/Modify.
Введите выражение в поле Expression так же, как в диалоговом окне Watch Properties (см рис 2.12). Затем щелкните на кнопке Evaluate для того, чтобы увидеть результат в поле Result. Если выражение состоит только из имени простой переменной (не массива или структуры!), можете ввести новое значение для переменной в поле New Value и, щелкнув на кнопке Modify, присвоить переменной новое значение. Это позволяет корректировать значения переменных в процессе отладки, не останавливаясь и не перекомпилируя всю программу, что сбережет ваше время и нервы, и даст возможность, найдя одну ошибку, искать другие, а исправлением первой ошибки заняться чуть позже.
Рис 2.14 Использование диалогового окна Evaluate/Modify для проверки изменения отдельной переменной.

Диалоговое окно Evaluate/Modify — немодальное, т. е. вы можете не закрывать его, продолжая отладку. Однако учтите, что в отличие от окна Watch List диалоговое окно Evaluate/Modify не отслеживает изменения значений переменных и для получения информации о текущем состоянии переменной вам необходимо воспользоваться кнопкой Evaluate.
Так же, как и окно Watch List, диалоговое окно Evaluate/Modify может выводить сообщения об ошибках, если отладчик не в состоянии вывести информацию о переменных. И точно так же не выводится информация о выражениях, содержащих вызов функций.
Как видите, окно Watch List и диалоговое окно Evaluate/Modify очень похожи, но каждое из них имеет свои преимущества в различных ситуациях. Обратите внимание на одно существенное отличие диалогового окна Evaluate/Modify его вывод выполняется в поле с несколькими строками, а потому оно более удобно для просмотра структур и объектов.

Установка точек останова
Точка останова (breakpoint) — своеобразный знак STOP для отладчика (на полосе слева в окне редактора она и выглядит как маленький красный значок). Когда ваше приложение запущено под отладчиком и доходит до строки, в которой находится точка останова, оно прекращает работу и ждет ваших дальнейших распоряжений. Такие точки могут быть условными и безусловными. Отладчик всегда останавливается на точке безусловного останова и может останавливаться в точке условного останова, когда выполнено условие. Интегрированный отладчик Delphi поддерживает два типа условий — логическое и по количеству проходов. Ниже рассмотрены оба типа.
Установить точки останова можно следующими способами:

  • Поместите курсор редактирования на выбранную строку программы и нажмите клавишу команды Toggle Breakpoint (по умолчанию это клавиша > ) для установки или удаления точки останова в этой строке. То же самое можно выполнить и с помощью контекстного меню.
  • Выберите команду Run/Add Breakpoint, и откроется диалоговое окно Edit breakpoint (рис 2.15). Для установки простейшей точки останова просто щелкните на кнопке New. Вы также можете использовать поля Filename и Line Number для установки точек останова в другом файле или строке за пределами текущей позиции курсора. Поля Condition и Pass count используются для установки точки условного останова.

После установки одной или нескольких точек останова можете использовать окно Breakpoint List для управления ими. Для вызова окна Breakpoint List выберите команду View/Breakpoints (рис. 2.16). В этом окне можете щелкнуть на строке конкретной точки правой кнопкой мыши и в контекстном меню отключить точку останова с помощью команды Disable (вновь включить точку останова можно с помощью команды Enable) или удалить ее с помощью команды Delete. Команды View Source и Edit Source активизируют окно с текущим файлом исходного текста, при этом команда Edit Source устанавливает курсор в строку с точкой останова. Команда Properties выводит диалоговое окно Edit breakpoint, показанное на рис. 2.15, позволяя тем самым изменять параметры точки останова. Рис. 2.15. Использование диалогового окна Edit breakpoint для установки новой точки останова. Рис. 2.16. Использование окна Breakpoint list для управления точками останова.

После щелчка правой кнопкой мыши в окне при невыбранной точке останова выводится контекстное меню, в котором команда Add служит для добавления новой точки, Delete All удаляет все точки останова, а команды Disable All и Enable All отключают или включают все точки останова в списке.
Для превращения безусловной точки останова в условную, необходимо вызвать диалоговое окно Edit breakpoint (см. рис. 2.15) и ввести условное выражение или количество проходов в соответствующие поля.
Условное выражение, введенное в поле Condition, может быть любым логическим выражением. По достижении точки останова отладчик вычисляет значение выражения и, если результат ложен, продолжает выполнение программы. Если выражение истинно, выполнение программы приостанавливается. Как обычно, выражение не должно использовать вызов функции. Такие точки останова полезны, если вы можете попасть в интересующий вас фрагмент кода различными путями, но вы хотите остановить выполнение программы только при достижении каких-либо конкретных условий.
Ненулевое значение, введенное в поле Pass count, дает отладчику задание продолжать выполнение программы при прохождении через точку останова, пока через нее не будет выполнено соответствующее количество проходов. При каждом проходе через точку останова отладчик уменьшает значение счетчика на единицу и по достижении нулевого значения программа приостанавливается. Такой метод полезен при работе с циклами, особенно если вы знаете, что ошибка происходит после определенного количества циклов.
Сейчас, когда вы изучили основы технологии отладки, вероятно, у вас возникло желание поставить точку останова у себя в голове и поработать с точками останова в программах. Кстати, один из отличных методов понять, как работает та или иная программа, — проследить за ее пошаговым выполнением, а поскольку ни установка точек останова, ни просмотр или изменение переменных не изменяют текста программы, вы можете работать смело, не опасаясь каким-либо образом «поломать» используемое в учебных целях приложение.

Отладка DLL
В предыдущих версиях Delphi для отладки библиотек динамической компоновки требовался внешний отладчик (Turbo Debugger for Windows). Delphi 4 внесла возможность отладки DLL в список своих возможностей. Windows не может загрузить DLL без предварительной загрузки использующего ее ЕХЕ, поэтому вам с начало придется набросать простенькую программку, использующую интересующую вас DLL. В главном меню выберите команду Run/Parameters для вывода диалогового окна Run Parameters. Если текущий проект— DLL (DPR-файл начинается ключевым словом library, а не program), поле Host Application будет доступно, и в нем вам надо либо ввести имя использующей DLL программы, либо выбрать его с помощью кнопки Browse.
После выбора приложения запуск и отладка DLL становятся обычной рутинной работой со всеми возможностями, используемыми при отладке программ, — установкой точек останова, просмотром значений переменных и т.д.
Точно так же вы будете отлаживать и свои компоненты ActiveX, и объекты автоматизации OLE.

Окно CPU (дизассемблер)
Окно CPU предоставляет возможность увидеть работу приложения на уровне языка ассемблера . Те, кто использовали отладчик Turbo Debugger for Windows, должны знать возможности, предоставляемые таким окном. Эффективное его использование предполагает знание ассемблера Intel x86 и архитектуры процессора, так что, если вы не вполне уверенно себя чувствуете, можете пропустить этот раздел.
Окно CPU требуется крайне редко, но если в нем возникла необходимость, значит, это действительно необходимость. Это — ultima ratio, последний довод, и используется он в безвыходных положениях, когда обычная трассировка кода не позволяет найти, понять и исправить ошибки. Только в таких случаях окно CPU и проход по ассемблерным инструкциям может приподнять завесу над причиной возникновения ошибок.
Чтобы использовать окно CPU необходимо его включить (по умолчанию оно отключено). Для этого придется использовать программу RegEdit из поставки Windows 95 (Windows NT). Запустите Reg E dit и пробирайтесь по иерархическому дереву папок. Сначала откройте папку HKEY_CURRENT_USER. Во вложенной ветви зайдите в папку Software, затем — в Borland, Delphi и, наконец, в 4.
Одна из папок называется Debugging. Щелкните на ней и, когда она откроется, появится список пар Имя/Данные в окошке справа. Добавьте новое значение с именем EnableCPU и значением 1.
При следующем запуске Delphi вы увидите новый подпункт меню View/CPU Window.
Для вывода окна выберите View/CPU Window.

Перечислим панели

  • Code pane Панель кода представляет дизассемблированный код в окрестности текущей точки выполнения (если вы не отлаживаете приложение, окно будет полупустым). Кроме того, панель показывает исходный текст строк, соответствующих выполняемому коду. В окне редактирования точка выполнения индицируется маленьким зеленым значком. При пошаговом проходе значок точки выполнения синхронно перемещается по окну CPU и окну редактирования.
  • Register pane. В панели регистров отображается содержимое 16 регистров процессора. Значения регистров, изменившиеся в результате выполнения последней операции, выделены красным цветом.
  • Flags pane. Панель флагов показывает состояние 14 флагов процессора. Установленный флаг представляется значением 1, сброшенный флаг значением 0. В зависимости от процессора некоторые флаги могут быть недоступными.
  • Stack pane. Панель стека показывает содержимое стека приложения. Вы можете изменять представление содержимого стека с помощью контекстного меню.
  • Data pane. По умолчанию в панели данных выводится содержимое глобального сегмента данных приложения. Ее вид можно изменить так же, как и вид панели стека.

Каждая из панелей в окне CPU имеет собственное контекстное меню. Вы можете поэкспериментировать с пунктами меню и получить более полное представление о возможностях манипулирования панелями.

Окно состояния подзадач.
Окна Thread Status, Modules и Call Stack предоставляют дополнительную информацию, которая может быть полезна при отладке приложения.
В окне Thread Status перечислены все активные подзадачи текущего процесса. Для просмотра состояния подзадач выберите команду View/Threads, и на экране появится окно Thread Status (рис 2.17).
Рис 2.17 . Использование окна Thread Status для просмотра атрибутов подзадач в приложении

В четырех колонках окна представлена следующая информация:

  • Thread ID. Уникальный идентификатор подзадачи, присвоенный ей операционной системой.
  • State. Состояние подзадачи, обычно — Running или Stopped. Если ваше приложение запущено, но ожидает ввода от пользователя, состояние выводится как Runnable.
  • Status. Статус подзадачи может иметь одно из четырех значений. Breakpoint означает, что поток остановлен в точке останова. Stepped— подзадача находится в режиме пошагового выполнения. Faulted— остановка подзадачи из-за исключительной ситуации и Unknown — статус неизвестен.
  • Location. В этой колонке выводится строка исходного кода, соответствующего текущей точке выполнения подзадачи. Если отладчик не в состоянии определить строку исходного текста, выводится 32-битовый адрес точки выполнения.

Если вами разработано приложение с несколькими подзадачами, и вы хотите отладить одну из подзадач, можете сделать ее основной с помощью окна Thread Status. Выберите подзадачу, которою вы хотите сделать текущей, и щелкните на ней правой кнопкой мыши. Выберите из контекстного меню команду Make Current. При этом фокус выполнения будет передан выбранной подзадаче, и вы сможете отлаживать ее как основную задачу.
В контекстном меню окна содержатся две команды — View Source и Go to Source. Они могут пригодиться для того, чтобы проследить за точкой выполнения другой подзадачи без передачи ей фокуса.

Окно Modules
В окне Modules отображаются все модели (ЕХЕ-файл вашего приложения и все используемые динамические библиотеки), которые располагаются в адресном пространстве приложения. В него входят непосредственно подключенные DLL и библиотеки, подключенные через другие библиотеки, а также библиотеки, загруженные операционной системой. Чтобы увидеть это окно, изображенное на рис 2.18. выберите команду View/Modules. В окне информация выводится в трех столбцах Name (имя модуля), Address (адрес начала кода модуля) и Path (полный путь каталога, из которого был загружен модуль). Информация о каталоге может быть важна, если возможна загрузка модуля не из того каталога, из которого ожидалась, например, в более старой версии. Информация об адресе обычно используется при отладке в окне CPU.

Окно Call Stack
В этом окне представлен список всех функций и процедур, вызванных к моменту достижения точки выполнения и работа которых приостановлена. Для открытия этого окна, показанного на рис 2.19, используйте команду View/Call Stack. Рис. 2.18. Использование окна Modules для вывода списка модулей, используемых приложением. Рис. 2.19 Использование окна Call Stack для определения всех вызванных функций и процедур.

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

Трассировка исходного кода VCL
Если вы используете соответствующую версию поставки Delphi 4, значит, в нее входят исходные тексты VCL (Visi Component Library). В поставку VCL входят скомпилированными без отладочной информации, что означает, что при отладке вы не сможете пройти код пошагово. Нет особой необходимости трассировать код VCL, но если вы хотите убедиться, что ошибка не в VCL, или посмотреть, как работает функция, придется перекомпилировать модули, которые нужно трассировать, с отладочной информацией.

Совет: Некоторые стандартные модули VCL требуют компиляции с отключенной опцией Overflow Checking для корректной работы. Поэтому при перекомпиляции убедитесь, что эта опция компилятора отключена.

$DebugInfo — Директива компилятора Delphi

Давным-давно, когда компьютеры были большими, а именно — лет двадцать назад, отладка заключалась в копании в огромных кипах бумаги с исходными текстами и распечатках результатов работы и потреблении невероятного количества кофеина, а зачастую и анальгина. Современный программист, особенно если он программирует на Delphi, больше не чернорабочий от программирования с крепкими от переворачивания центнеров бумаги мускулами, а «белый воротничок», окруженный разнообразными »электронными мухобойками», предоставляемыми Delphi.
Интегрированный отладчик Delphi переполнен полезными, не очень полезными и совсем бесполезными возможностями, и кажется, что изучить их просто невозможно. Однако использование отладчика D elphi просто, как апельсин: ведь когда вы компилируете свою программу и запускаете ее из среды Delphi, вы уже пользуетесь встроенным отладчиком, хотя, вероятно, и не подозреваете об этом. Как всегда, 90% проблем решается 10% возможностей программного обеспечения, а потому все разнообразие работы с отладчиком вы можете изучить позднее, при решении оставшихся 10% ваших проблем.

Настройка IDE для отладки
Для работы со встроенным отладчиком Delphi 4 его интегрированная среда разработки (IDE) предлагает целую серию установок, большинство из которых вам лучше не трогать, а оставить, как есть (по умолчанию). Однако если вы все-таки решили изменить установки, выберите команду Tools/Options и в появившемся диалоговом окне Environment Options щелкните на вкладке Preferences (она показана на рис 2.5)
Ниже перечислены опции вкладки Preferences и их функции.

  • Integrated Debugging. Позволяет включать и отключать встроенный отладчик. Если вы отключите отладчик, отладочные команды в меню Run станут недоступными.
    Совет: Если у вас возникли проблемы при запуске приложения из интегрированной среды, возможно, это вызвано конфликтом встроенного отладчика с другими приложениями, запущенными в системе. Попробуйте отключить встроенный отладчик и, если это поможет, будьте уверены — проблема кроется в одном из уже запущенных в системе приложений. Лучшим решением будет перезагрузка и последующий запуск только абсолютно необходимых приложений.
    Рис. 2.5. Использование вкладки Preferences для настройки интегрированного отладчика Delphi.
  • Step Program Block. Эта опция определяет, должен ли отладчик останавливаться перед началом выполнения основного блока begin. . . end при трассировке программы. Обычно данная опция отключена, и включать ее имеет смысл при добавлении кода в основной блок программы либо при отладке консольного приложения.
  • Hide Designers on Run. Когда эта опция включена, окно Object Inspector и формы, использующиеся при разработке приложения, перед запуском программы на выполнение закрываются. Отключение опции позволяет запускать программу быстрее, но эффект перекрывается используемыми незакрытыми ресурсами приложения. Впрочем, будет ли выбрана эта опция, зависит от пользователя.
  • Break on Exception. При включенной опции IDE всегда перехватывает исключительные ситуации и выводит окно сообщения, даже если в программе исключительная ситуация обрабатывается блоком try. . .except. Включение этой опции упростит отладку, так как выводимые сообщения при этом будут более информативными, чем сообщения обработчика, установленные по умолчанию (сравните рис. 2.6 и 2.7). Помимо этого, IDE размещает окно редактора поверх остальных и выделяет строку, вызвавшую исключительную ситуацию.

Рис. 2.6. Сообщение об исключительной ситуации при включенной опции Break on Exception Рис. 2.7. Сообщение об исключительной ситуации, выводимое обработчиком по умолчанию

Совет: Конечно, опция Break on Exception полезна, но может привести в растерянность новичка в Delphi, особенно когда сообщается об исключительной ситуации, которую должен обработать блок try. . .except. Вы можете либо отключить эту опцию, либо запустить приложение не из среды Delphi, чтобы увидеть его работу глазами конечного пользователя.

Minimize on Run Опция сворачивает окно IDE при запуске приложения Подобно опции Hide Designers on Run, ее установка зависит исключительно от личных предпочтений программиста На странице Display диалогового окна Environment Options есть еще одна установка- опция Visible Gutter. Она включает или отключает отображение серой вертикальной полосы, расположенной слева от окна редактирования (рис. 2.8), на которой мнемоническими значками отображается отладочная информация

Включение в код отладочной информации
Перед началом отладки следует убедиться, что в приложение включена отладочная информация Delphi.
Для компиляции проекта с отладочной информацией следует выполнить команду Project/Options и в диалоговом окне Project Options выбрать вкладку Compiler (рис. 2.9).
Рис. 2.8. Окно редактора с отладочными значками Рис. 2.9 Вкладка Compiler диалогового окна Project Options

Включение отладочной информации регулируется следующими установками

  • Debug Information. Опция контролирует включение отладочной информации. При отключении этой опции вы не сможете трассировать код или ставить точки прерывания в любом модуле. Опция эквивалентна директивам компилятора $D и $DEBUGINFO
  • Local Symb ols. Опция контролирует включение информации о локальных переменных, декларированных, например, внутри функций, процедур и раздела implementation. Вряд ли у вас возникнет необходимость в отключении этой опции, тем более что она игнорируется при выключенной предыдущей опции . Эквивалентные директивы компилятора- $L и $LOCALSYMBOLS.
  • Symbol Info. Эту опцию нельзя целиком отнести к разряду отладочных, так как ее действие направлено на броузер объектов, а не на встроенный отладчик. Если опция включена, броузер объектов сможет выводить информацию для объектов, определенных в модулях Опция игнорируется при выключенных предыдущих двух опциях Эквивалентные директивы компилятора — $Y и $REFERENCEINFO

Обычно вы будете включать опции Debug Information и Local Symbols для пошаговой трассировки приложения. Однако, как упоминалось ранее, вы можете отключить отладочную информацию для некоторых модулей (просто используйте соответствующую директиву в начале модуля).

Использование директивы $D- автоматически отключает опции Local Symbols и Symbol Info, так что вам не надо отключать их отдельно.

Совет: Если вы распространяете модули Delphi в виде DCU-файлов (например, VCL) и не распространяете их исходных текстов позаботьтесь о том, чтобы в скомпилированных модулях не содержалась отладочная информация

Пошаговая отладка
Одна из самых распространенных задач отладки — выполнение программы шаг за шагом, по одной строке за раз для проверки правильности выполнения. При пошаговом прохождении кода отладчик выводит окно редактирования с выполняемой программой. Точка выполнения, показывающая следующую выполняемую строку программы, представляется в виде зеленой стрелки, расположенной слева от области исходного текста в окне редактирования.
После успешной компиляции модуля на полосе отладочной информации каждая строка кода, внесшая свой вклад в модуль, будет отмечена маленьким, синим кружком. Если же строка не помечена, значит, здесь поработал оптимизатор. Поскольку для таких строк выполняемый код не сгенерирован эти строки не будут помечены точкой выполнения.
Интегрированная среда Delphi предоставляет пользователю несколько команд пошаговой отладки доступных в меню Run (рис 2.10)

Рис 2.10 Используйте меню Run для выполнения команд отладки

Ниже перечислены команды отладки.

  • Run. Выбор этой команды запускает приложение на выполнение в обычном режиме. Вы можете использовать ее как для запуска приложения, так и для продолжения его работы после какого-либо прерывания выполнения (например, по точке останова). Если включена опция Break on Exception, используйте команду для продолжения работы после получения сообщения об исключительной ситуации
  • Step Over. Когда точка выполнения находится на строке содержащей вызов процедуры или функции, используйте эту команду для выполнения строки, включая вызовы в один шаг, без прохождения отдельных строк вызываемых функций. Точка выполнения перемещается при выполнении на следующую строку
  • Trace Into. В отличие от предыдущей команды, эта опция отработает пошаговую отладку вызываемых процедур и функций. Другими словами, если, например, в строке вызывается некая процедура, то при выполнении этой команды точка выполнения перейдет на первую строку процедуры. Однако если в строке нет таких вызовов, значит, последние две команды идентичны. Будьте осторожны при пошаговой трассировке обработчика события OnPaint. Поскольку при пошаговой отладке окно редактора размещается поверх других окон, требуется перерисовка окна приложения, для чего вызывается обработчик события OnPaint. Вы попадаете в замкнутый круг, точнее- в бесконечный цикл вызовов одного и того же обработчика. Тем не менее, стоит лишь проследить, чтобы окна приложения и редактора не перекрывались, и проблема разрешится сама собой.
  • Trace to Next Source Line. Иногда ваш код вызывает другой код косвенно, например, при вызове функции, которая запускает обработчик события, или при вызове функции Windows API, которая, в свою очередь, запускает функцию косвенного вызова. Поскольку такие вызовы косвенные, отладчик не видит вызова и не отслеживает пошагового выполнения таких вызовов . Однако использование описываемой команды приводит к отслеживанию таких вызовов и останову отладчика на первой строке вызываемой таким образом функции или процедуры.
  • I Run to Cursor. Зачастую вам вовсе не хочется в поисках ошибки, местоположение которой с какой-то точностью вам известно, пошагово добираться до нужного места через сотни, а то и тысячи строк кода. В таком случае просто поместите курсор на нужную вам строку программы в окне редактирования и используйте команду Run to Cursor. Эти действия эквивалентны временному помещению точки останова в необходимую вам строку программы, и после выполнения предшествующего строке кода работа программы приостанавливается. Если вы пытаетесь выполнить программу до позиции курсора, который находится в строке, не содержащей отладочной информации, вы получите сообщение об ошибке, показанное на рис. 2.11.

Рис. 2.11. Это сообщение о том, что вы пытаетесь остановить выполнение программа на строке, не содержащей отладочной информации.

  • Show Execution Point. Эта команда заставляет среду разработки открыть окно редактора и показать выполняемую в настоящее время строку программы. Она полезна в случаях, когда вы, например, закрыли или свернули окно редактора во время отладки (обычно при нормальном состоянии окна отладчик делает это автоматически).
  • Program Pause. Выбор этой команды немедленно останавливает выполнение программы. Она особенно полезна при зацикливании программы.
  • Program Reset. Если вы достаточно «наотлаживались» и хотите завершить работу своей программы или запустить ее заново, используйте эту команду. Она немедленно прекратит выполнение программы и вернет вас в среду разработчика.

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

Просмотр значений переменных
При пошаговом прохождении программы в отладчике вы, несомненно, захотите узнать, что содержится в различных переменных. Для этого можете использовать окно просмотра переменных Watch List, которое предоставляет возможность пассивно просматривать содержимое одной или нескольких переменных, или диалоговое окно Evaluate/Modify, позволяющее работать только с одной переменной (в нем можно не только просмотреть, но и изменить ее содержимое).
Для просмотра значения переменной используйте команду Run/AddWatch или установите указатель мыши на переменную в окне редактирования, щелкните правой кнопкой мыши и выберите из контекстного меню команду Add Watch at Cursor. После этого появится диалоговое окно Watch Properties, показанное на рис. 2.12. Введите имя переменной в поле Expression (если оно не появилось там автоматически). Обратите внимание на то, что вы можете просматривать значения не только переменных, но и выражений типа х*(y+z). Единственное ограничение- выражение не может содержать вызовов функций, поскольку это может вызвать побочный эффект, связанный с незапланированным вызовом функции, описанный выше, в подразделе »Использование директивы Assert». Допускается также просмотр значений записей, массивов и других структурированных элементов.
Поле Repeat Count используется в том случае, если у вас есть большой массив, и вы хотите просмотреть его часть. Предположим, что вам надо знать значения элементов 826-833 следующего массива

var
BigArray: array[1..1000] of Integer;

Вы не можете просмотреть массив BigArray, так как 1 000 элементов просто не поместятся в окне (да и пролистать ненужные вам 825 элементов — работенка немалая!) Вместо этого вы просите показать вам значение BigArray [826] и устанавливаете параметр Repeat Count равным 8. При этом вам будут показаны значения восьми элементов массива- от 826 по 833.
Использование поля Digits позволяет определить количество значащих цифр при выводе числа с плавающей точкой.
Отключенная опция Enabled предотвращает вывод значения переменной, однако , среда будет хранить все параметры, заданные для ее просмотра. Так, вы можете временно убрать с экрана информацию о переменной, которая в настоящий момент вам не нужна, и быстро восстановить ее на экране при необходимости без повторного ввода характеристик просмотра.
В диалоговом окне имеется также набор переключателей для выбора способа представления переменной. Значение Default позволяет среде разобраться с типом переменной самостоятельно. Как правило, такое решение оптимально, однако в любой момент вы можете представить переменную как переменную того типа, который вас интересует. Опция Memory dump представляет информацию как набор байтов, что бывает полезно, когда необходимо увидеть внутреннее представление информации в переменной.
На рис 2.13 отображены значения нескольких переменных в окне Watch List. Кроме того, в некоторых случаях отладчик выводит информацию о причинах, по которым содержимое переменной недоступно.
Рис. 2.12. Использование диалогового окна Watch Properties для добавления или изменения набора переменных в окне просмотра. Рис. 2.13. Просмотр переменных.

Смысл приведенных сообщений поясняется ниже

  • Variable ‘X’ inaccessible here due to optimization(Переменная ‘X’ недоступна из-за оптимизации). В этой точке значение переменной просмотреть невозможно (иногда это можно сделать в другом месте программы), так как для нее не выделена память из-за оптимизации программы компилятором.
  • Symbol was eliminated by linker (Переменная удалена компоновщиком). Переменная удалена из кода программы компоновщиком, так как на нее нет ни одной ссылки в тексте программы.

Отладчик также выводит сообщение об ошибке, если имя переменной написано неправильно, например вы запросили значение Foo [5], в то время как переменная Foo массивом не является.

Совет: Когда вы пытаетесь просмотреть свойства объекта, выводимые значения могут оказаться бессмысленными. Многие свойства объектов, выглядящие как переменные, на самом деле являются вызовами функций. Отладчик не вызывает функции для определения значений, а потому корректные значения при таком просмотре вы получить не можете. Выход — в объявлении новых переменных, присвоении им значений свойств и просмотре не свойств, а новых переменных. Неприятности могут начаться из-за слишком умного оптимизатора, который сообразит, что, раз в программе значение переменной больше не используется, ее можно выбросить без ущерба для программы (увы, но не для отладки программы!) Если это происходит, используйте глобальные переменные, т.е. переменные, объявленные вне функции или процедуры. Отладчик всегда корректно отобразит значения глобальных переменных.

Диалоговое окно Evaluate/Modify
Для вывода диалогового окна Evaluate/Modify выберите команду Run/Evaluate/Modify (рис 2.14). Другой способ вызова диалогового окна — установить курсор в окне редактирования на необходимой вам переменной, щелкнуть правой кнопкой мыши и в контекстном меню выбрать команду Evaluate/Modify.
Введите выражение в поле Expression так же, как в диалоговом окне Watch Properties (см рис 2.12). Затем щелкните на кнопке Evaluate для того, чтобы увидеть результат в поле Result. Если выражение состоит только из имени простой переменной (не массива или структуры!), можете ввести новое значение для переменной в поле New Value и, щелкнув на кнопке Modify, присвоить переменной новое значение. Это позволяет корректировать значения переменных в процессе отладки, не останавливаясь и не перекомпилируя всю программу, что сбережет ваше время и нервы, и даст возможность, найдя одну ошибку, искать другие, а исправлением первой ошибки заняться чуть позже.
Рис 2.14 Использование диалогового окна Evaluate/Modify для проверки изменения отдельной переменной.

Диалоговое окно Evaluate/Modify — немодальное, т. е. вы можете не закрывать его, продолжая отладку. Однако учтите, что в отличие от окна Watch List диалоговое окно Evaluate/Modify не отслеживает изменения значений переменных и для получения информации о текущем состоянии переменной вам необходимо воспользоваться кнопкой Evaluate.
Так же, как и окно Watch List, диалоговое окно Evaluate/Modify может выводить сообщения об ошибках, если отладчик не в состоянии вывести информацию о переменных. И точно так же не выводится информация о выражениях, содержащих вызов функций.
Как видите, окно Watch List и диалоговое окно Evaluate/Modify очень похожи, но каждое из них имеет свои преимущества в различных ситуациях. Обратите внимание на одно существенное отличие диалогового окна Evaluate/Modify его вывод выполняется в поле с несколькими строками, а потому оно более удобно для просмотра структур и объектов.

Установка точек останова
Точка останова (breakpoint) — своеобразный знак STOP для отладчика (на полосе слева в окне редактора она и выглядит как маленький красный значок). Когда ваше приложение запущено под отладчиком и доходит до строки, в которой находится точка останова, оно прекращает работу и ждет ваших дальнейших распоряжений. Такие точки могут быть условными и безусловными. Отладчик всегда останавливается на точке безусловного останова и может останавливаться в точке условного останова, когда выполнено условие. Интегрированный отладчик Delphi поддерживает два типа условий — логическое и по количеству проходов. Ниже рассмотрены оба типа.
Установить точки останова можно следующими способами:

  • Поместите курсор редактирования на выбранную строку программы и нажмите клавишу команды Toggle Breakpoint (по умолчанию это клавиша > ) для установки или удаления точки останова в этой строке. То же самое можно выполнить и с помощью контекстного меню.
  • Выберите команду Run/Add Breakpoint, и откроется диалоговое окно Edit breakpoint (рис 2.15). Для установки простейшей точки останова просто щелкните на кнопке New. Вы также можете использовать поля Filename и Line Number для установки точек останова в другом файле или строке за пределами текущей позиции курсора. Поля Condition и Pass count используются для установки точки условного останова.

После установки одной или нескольких точек останова можете использовать окно Breakpoint List для управления ими. Для вызова окна Breakpoint List выберите команду View/Breakpoints (рис. 2.16). В этом окне можете щелкнуть на строке конкретной точки правой кнопкой мыши и в контекстном меню отключить точку останова с помощью команды Disable (вновь включить точку останова можно с помощью команды Enable) или удалить ее с помощью команды Delete. Команды View Source и Edit Source активизируют окно с текущим файлом исходного текста, при этом команда Edit Source устанавливает курсор в строку с точкой останова. Команда Properties выводит диалоговое окно Edit breakpoint, показанное на рис. 2.15, позволяя тем самым изменять параметры точки останова. Рис. 2.15. Использование диалогового окна Edit breakpoint для установки новой точки останова. Рис. 2.16. Использование окна Breakpoint list для управления точками останова.

После щелчка правой кнопкой мыши в окне при невыбранной точке останова выводится контекстное меню, в котором команда Add служит для добавления новой точки, Delete All удаляет все точки останова, а команды Disable All и Enable All отключают или включают все точки останова в списке.
Для превращения безусловной точки останова в условную, необходимо вызвать диалоговое окно Edit breakpoint (см. рис. 2.15) и ввести условное выражение или количество проходов в соответствующие поля.
Условное выражение, введенное в поле Condition, может быть любым логическим выражением. По достижении точки останова отладчик вычисляет значение выражения и, если результат ложен, продолжает выполнение программы. Если выражение истинно, выполнение программы приостанавливается. Как обычно, выражение не должно использовать вызов функции. Такие точки останова полезны, если вы можете попасть в интересующий вас фрагмент кода различными путями, но вы хотите остановить выполнение программы только при достижении каких-либо конкретных условий.
Ненулевое значение, введенное в поле Pass count, дает отладчику задание продолжать выполнение программы при прохождении через точку останова, пока через нее не будет выполнено соответствующее количество проходов. При каждом проходе через точку останова отладчик уменьшает значение счетчика на единицу и по достижении нулевого значения программа приостанавливается. Такой метод полезен при работе с циклами, особенно если вы знаете, что ошибка происходит после определенного количества циклов.
Сейчас, когда вы изучили основы технологии отладки, вероятно, у вас возникло желание поставить точку останова у себя в голове и поработать с точками останова в программах. Кстати, один из отличных методов понять, как работает та или иная программа, — проследить за ее пошаговым выполнением, а поскольку ни установка точек останова, ни просмотр или изменение переменных не изменяют текста программы, вы можете работать смело, не опасаясь каким-либо образом «поломать» используемое в учебных целях приложение.

Отладка DLL
В предыдущих версиях Delphi для отладки библиотек динамической компоновки требовался внешний отладчик (Turbo Debugger for Windows). Delphi 4 внесла возможность отладки DLL в список своих возможностей. Windows не может загрузить DLL без предварительной загрузки использующего ее ЕХЕ, поэтому вам с начало придется набросать простенькую программку, использующую интересующую вас DLL. В главном меню выберите команду Run/Parameters для вывода диалогового окна Run Parameters. Если текущий проект- DLL (DPR-файл начинается ключевым словом library, а не program), поле Host Application будет доступно, и в нем вам надо либо ввести имя использующей DLL программы, либо выбрать его с помощью кнопки Browse.
После выбора приложения запуск и отладка DLL становятся обычной рутинной работой со всеми возможностями, используемыми при отладке программ, — установкой точек останова, просмотром значений переменных и т.д.
Точно так же вы будете отлаживать и свои компоненты ActiveX, и объекты автоматизации OLE.

Окно CPU (дизассемблер)
Окно CPU предоставляет возможность увидеть работу приложения на уровне языка ассемблера . Те, кто использовали отладчик Turbo Debugger for Windows, должны знать возможности, предоставляемые таким окном. Эффективное его использование предполагает знание ассемблера Intel x86 и архитектуры процессора, так что, если вы не вполне уверенно себя чувствуете, можете пропустить этот раздел.
Окно CPU требуется крайне редко, но если в нем возникла необходимость, значит, это действительно необходимость. Это — ultima ratio, последний довод, и используется он в безвыходных положениях, когда обычная трассировка кода не позволяет найти, понять и исправить ошибки. Только в таких случаях окно CPU и проход по ассемблерным инструкциям может приподнять завесу над причиной возникновения ошибок.
Чтобы использовать окно CPU необходимо его включить (по умолчанию оно отключено). Для этого придется использовать программу RegEdit из поставки Windows 95 (Windows NT). Запустите Reg E dit и пробирайтесь по иерархическому дереву папок. Сначала откройте папку HKEY_CURRENT_USER. Во вложенной ветви зайдите в папку Software, затем — в Borland, Delphi и, наконец, в 4.
Одна из папок называется Debugging. Щелкните на ней и, когда она откроется, появится список пар Имя/Данные в окошке справа. Добавьте новое значение с именем EnableCPU и значением 1.
При следующем запуске Delphi вы увидите новый подпункт меню View/CPU Window.
Для вывода окна выберите View/CPU Window.

  • Code pane Панель кода представляет дизассемблированный код в окрестности текущей точки выполнения (если вы не отлаживаете приложение, окно будет полупустым). Кроме того, панель показывает исходный текст строк, соответствующих выполняемому коду. В окне редактирования точка выполнения индицируется маленьким зеленым значком. При пошаговом проходе значок точки выполнения синхронно перемещается по окну CPU и окну редактирования.
  • Register pane. В панели регистров отображается содержимое 16 регистров процессора. Значения регистров, изменившиеся в результате выполнения последней операции, выделены красным цветом.
  • Flags pane. Панель флагов показывает состояние 14 флагов процессора. Установленный флаг представляется значением 1, сброшенный флаг значением 0. В зависимости от процессора некоторые флаги могут быть недоступными.
  • Stack pane. Панель стека показывает содержимое стека приложения. Вы можете изменять представление содержимого стека с помощью контекстного меню.
  • Data pane. По умолчанию в панели данных выводится содержимое глобального сегмента данных приложения. Ее вид можно изменить так же, как и вид панели стека.

Каждая из панелей в окне CPU имеет собственное контекстное меню. Вы можете поэкспериментировать с пунктами меню и получить более полное представление о возможностях манипулирования панелями.

Окно состояния подзадач.
Окна Thread Status, Modules и Call Stack предоставляют дополнительную информацию, которая может быть полезна при отладке приложения.
В окне Thread Status перечислены все активные подзадачи текущего процесса. Для просмотра состояния подзадач выберите команду View/Threads, и на экране появится окно Thread Status (рис 2.17).
Рис 2.17 . Использование окна Thread Status для просмотра атрибутов подзадач в приложении

В четырех колонках окна представлена следующая информация:

  • Thread ID. Уникальный идентификатор подзадачи, присвоенный ей операционной системой.
  • State. Состояние подзадачи, обычно — Running или Stopped. Если ваше приложение запущено, но ожидает ввода от пользователя, состояние выводится как Runnable.
  • Status. Статус подзадачи может иметь одно из четырех значений. Breakpoint означает, что поток остановлен в точке останова. Stepped- подзадача находится в режиме пошагового выполнения. Faulted- остановка подзадачи из-за исключительной ситуации и Unknown — статус неизвестен.
  • Location. В этой колонке выводится строка исходного кода, соответствующего текущей точке выполнения подзадачи. Если отладчик не в состоянии определить строку исходного текста, выводится 32-битовый адрес точки выполнения.

Если вами разработано приложение с несколькими подзадачами, и вы хотите отладить одну из подзадач, можете сделать ее основной с помощью окна Thread Status. Выберите подзадачу, которою вы хотите сделать текущей, и щелкните на ней правой кнопкой мыши. Выберите из контекстного меню команду Make Current. При этом фокус выполнения будет передан выбранной подзадаче, и вы сможете отлаживать ее как основную задачу.
В контекстном меню окна содержатся две команды — View Source и Go to Source. Они могут пригодиться для того, чтобы проследить за точкой выполнения другой подзадачи без передачи ей фокуса.

Окно Modules
В окне Modules отображаются все модели (ЕХЕ-файл вашего приложения и все используемые динамические библиотеки), которые располагаются в адресном пространстве приложения. В него входят непосредственно подключенные DLL и библиотеки, подключенные через другие библиотеки, а также библиотеки, загруженные операционной системой. Чтобы увидеть это окно, изображенное на рис 2.18. выберите команду View/Modules. В окне информация выводится в трех столбцах Name (имя модуля), Address (адрес начала кода модуля) и Path (полный путь каталога, из которого был загружен модуль). Информация о каталоге может быть важна, если возможна загрузка модуля не из того каталога, из которого ожидалась, например, в более старой версии. Информация об адресе обычно используется при отладке в окне CPU.

Окно Call Stack
В этом окне представлен список всех функций и процедур, вызванных к моменту достижения точки выполнения и работа которых приостановлена. Для открытия этого окна, показанного на рис 2.19, используйте команду View/Call Stack. Рис. 2.18. Использование окна Modules для вывода списка модулей, используемых приложением. Рис. 2.19 Использование окна Call Stack для определения всех вызванных функций и процедур.

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

Трассировка исходного кода VCL
Если вы используете соответствующую версию поставки Delphi 4, значит, в нее входят исходные тексты VCL (Visi Component Library). В поставку VCL входят скомпилированными без отладочной информации, что означает, что при отладке вы не сможете пройти код пошагово. Нет особой необходимости трассировать код VCL, но если вы хотите убедиться, что ошибка не в VCL, или посмотреть, как работает функция, придется перекомпилировать модули, которые нужно трассировать, с отладочной информацией.

Илон Маск рекомендует:  Типы переменных visual basic 6 0
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL