Отладка в Windows

Дополнительная сложность программ для Windows вызывает появление новых категорий ошибок. Turbo Debugger имеет ряд средств, которые помогут вам найти ошибке в программе для Windows.

Регистрация сообщений

Окно Windows Messages имеет ряд команд для трассировки и проверки получаемых программой оконных сообщений. С его помощью вы можете устанавливать точки останова по сообщениям (выполнение программы будет приостанавливаться при получении сообщения конкретным окном). Вы можете также регистрировать получаемые окном сообщения. Данное окно открывается командой View Message и имеет три области: область выбора окна, область класса сообщения и область регистрации.

Задание окна

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

Чтобы задать окно в TD32, используйте имя оконной процедуры, которая обрабатывает сообщения окна. Для этого с помощью команды Add в SpeedMenu области выбора окна откройте диалоговое окно Add Window Procedure to Watch (или наберите непосредственно ее имя в области). Затем наберите имя процедуры в поле ввода Window Identifier и нажмите Enter. Эту процедуру вы можете повторить для каждого окна, сообщения которому вы хотите отслеживать.

В TDW окно можно задать с помощью описателя окна или оконной процедуры, обрабатывающей его сообщения. В любом случае следует использовать диалоговое окно Add Window или Handle to Watch. Для его вывода выберите команду Add в SpeedMenu области выбора окна или наберите имя непосредственно в этой области. Кнопки Identify By этих окон позволяет вам выбрать способ спецификации окна. Это меню позволяет также отменить выбор окна. Для этого используются команды Remove (Ctrl+R) и Delete All (Ctrl+D).

Задание отслеживаемых сообщений

После задания окна Turbo Debugger по умолчанию перечисляет в области регистрации сообщения все сообщения WM_. Чтобы сократить число отслеживаемых сообщений, используйте диалоговое окно Set Message Filter, которое выводится командой Add в SpeedMenu области класса сообщения. Это окно позволяет задать класс сообщений или индивидуальные имена сообщений.

Чтобы задать конкретное сообщение для окна в области выбора окна, откройте диалоговое окно Set Message Filter и с помощью кнопки с зависимой фиксации выберите один из следующих классов сообщений:

All Messages Все оконные сообщения.
Mouse Сообщения, генерируемые событием "мыши".
Window Сообщения, генерируемые администратором окон.
Input Сообщения, генерируемые клавиатурным событием, или обращением пользователя к меню System, полосе прокрутки или блоку изменения размера.
System Сообщения, генерируемые изменениями в масштабе системы.
Initialization Сообщения, генерируемые при создании в приложении диалогового окна.
Clipboard Сообщения, генерируемые при обращении пользователя к буферу Clipboard.
DDE Сообщения динамического обмена данными, генерируемые при обмене данными между приложениями Windows.
Non-client Сообщения, генерируемые Windows для обслуживания неклиентной области окна приложения.
Other Любые сообщения, не попадающие в предыдущие категории (например, сообщения MDI).
Single Message Позволяет вам задать конкретное отслеживаемое сообщение.

Чтобы регистрировать одно сообщение, выберите Single Message и введите в поле ввода Single Message Name имя сообщения или его номер. Если вы хотите регистрировать для конкретного окна несколько классов или сообщений, то

Задание действия по сообщению

После спецификации окна и отслеживаемых сообщений нужно задать действие, выполняемое при поступлении сообщения. Turbo Debugger предусматривает в диалоговом окне Set Message Filter две кнопки Action: Break (приостановка выполнения программы) и Log (регистрация сообщения вы области регистрации окна Windows Messages). Break фактически означает установку точки останова по сообщения.

Если вы регистрируете сообщения для нескольких окон, не регистрируйте все сообщения. Большое число передаваемых между Windows и Turbo Debugger сообщений может привести к краху системы.

Отладка библиотек DLL

Динамически компонуемая библиотека DLL - это библиотека подпрограмм и ресурсов, компонуемая с приложением Windows на этапе выполнения. Это позволяет подпрограммам использовать одну копию подпрограмм, ресурсов и драйверов устройств. Когда приложению требуется доступ к DLL, Windows проверяет, загружена ли DLL в память. Если это так, то вторая копия не загружается.

DLL может загружаться программой в память двумя различными способами:

Выполнение DLL по шагам

При пошаговом выполнении функции DLL Turbo Debugger загружает идентификатор DLL, исходный код DLL в окно Windows и позиционирует курсор на вызываемую подпрограмму. Однако, перед загрузкой исходного кода в окно Module должны удовлетворяться следующие условия:

Turbo Debugger ищет исходный код DLL также, как и исходный код программ. Если DLL не содержит отладочной информации, то отладчик не может найти исходный код DLL и открывает окно CPU.

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

Если вы отлаживаете код запуска DLL, перед загрузкой DLL установите точку останова на первой строке программы. Это обеспечит приостановку программы при возврате и DLL.

Доступ к DLL и исходному коду модулей

Хотя Turbo Debugger обеспечивает прозрачное пошаговое выполнение функций DLL, вам может потребоваться доступ к DLL до того, как программа ее вызовет (например, в ней нужно установить точки останова или задать отслеживаемые выражения). Для доступа к выполняемому модулю, отличному от текущего загруженного, откройте с помощью команды View Modules (F3) диалоговое окно Load Module Source or DLL. Это диалоговое окно перечисляет все исходные модули, содержащиеся в текущем загруженном выполняемом файле. Блок списка DLL & Programs показывает все файлы .DLL и .EXE, загруженные Windows. (При работе с TDW в нем также выводятся все загруженные файлы .DRV и .FON.)

Символом точки (.) отмечены DLL, которые могут загружаться в Turbo Debugger (а также DLL с отладочной информацией и исходным кодом). Звездочка (*) показывает, что модуль загружен отладчиком. Так как ваши программы могут загружать DLL с помощью вызова LoadLibrary, в блоке списка могут показываться не все DLL.

Если вам нужен другой модуль исходного кода, подсветите нужный модуль в списке Source Module и используйте кнопку Load (или дважды щелкните на имени модуля "мышью"). Turbo Debugger открывает окно Module и выводит исходный код данного модуля.

Для доступа к выполняемому файлу, отличному от текущего, откройте диалоговое окно Load Module Source or DLL Symbols (F3), подсветите в блоке списка нужный файл и выберите командную кнопку Symbol Load. Turbo Debugger открывает окно Module с исходным кодом первого модуля выполняемого файла.

Чтобы добавить DLL к списку, откройте указанное диалоговое окно, активизируйте поле ввода DLL Name и введите имя соответствующей DLL. Чтобы добавить DLL к списку, нажмите кнопку Add DLL.

При выполнении по шагам функции DLL отладчик автоматически загружает таблицу идентификаторов и исходный код этой DLL. Чтобы предотвратить это, откройте диалоговое окно Load Module Source or DLL Symbols (F3), подсветите в списке нужную DLL, выберите кнопку No и щелкните "мышью" на OK. Turbo Debugger будет выполнять вызовы DLL как одну команду.

Отладка кода запуска DLL

Когда ваша программа загружает DLL, выполняется код запуска DLL. По умолчанию Turbo Debugger не выполняет по шагам этот код. Однако, если вам нужно проверить корректность загрузки DLL, то нужно отладить код запуска. Отладчик позволяет отлаживать два вида такого кода: код инициализации, непосредственно следующий за LibMain (по умолчанию) и скомпонованный с DLL код ассемблера. Этот код инициализирует процедуры запуска и эмулирует математические пакеты (этот режим отладки выбирается параметром -l командной строки отладчика).

Чтобы начать отладку кода запуска DLL, нужно перезагрузить программу (Run Program Reset или F2), а затем выполнить следующие шаги:

При отладке имейте в виде следующее:

Отладка мультинитевых программ

Окно Thread, которое открывается по команде View Thread, поддерживает мультинитевую среду Windows NT. Это окно содержит три области: списка нитей, детализации и информационную.

В информационной области перечисляется общая информация о нити. Поле Last указывает последнюю нить, выполненную перед передачей управления в Turbo Debugger, поле Current показывает нить, которая выводится в окнах отладчика, поле Total - общее число активных программных нитей, а поле Notify - Yes или No для статуса Notifu или Termination отдельных нитей. Общий статус устанавливается с помощью команды All Threads.

Область нитей

В этой области перечисляются все активные нити программы, идентифицируемые по номеру нити (назначаемому Windows NT) и имени. Turbo Debugger генерирует имя нити, когда ваша программа создает нить. Первая создаваемая нить называется Thread 1, затем Thread 2 и т.д. Это имя можно изменить.

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

Options Открывает диалоговое окно Thread Options, позволяющее задать параметры отдельных нитей. Кнопка Freeze этого окна позволяет "замораживать" и "размораживать" индивидуальные нити. Включение этой кнопки означает, что нить выполняться не будет. Для выполнения программы необходима хотя бы одна активная нить. Кнопка Notify or Tremination позволяет задать, должен ли отладчик уведомлять вас о завершении текущей (подсвеченной) нити (он генерирует сообщение и активизирует окно Module и CPU с текущим адресом программы). Чтобы задать уведомление для всех нитей, используйте команду меню All Threads. Поле ввода Thread Name позволяет изменить имя текущей нити.
Make Current Команда Make Current позволяет сменить нить, обрабатываемую отладчиком. Подсветите в области Threads List нить, которую вы хотите проверить, и нажмите Ctrl+M (или выберите Make Current).
Inspect Открывает окно Module или CPU, которое показывает для подсвеченной нити текущую точку выполнения. Этой команде эквивалентна клавиша Enter.
All Threads Открывает меню, команды которого относятся ко всем нитям программы. Это команды Thaw, Freeze, Enable Exit Notification и Disable Exit Notification.
Step Позволяет переключаться между All и Single. При выборе All клавиши F7 и F8 приводят к выполнению всех нитей программы, а Single позволяет выполнять только одну нить.

Область детализации

В этой области выводится подробная информация о нити, подсвеченной в области списка нитей. Первая строка показывает статус подсвеченной нити (приостановлена или выполняется) и ее приоритет. Операционная система устанавливает 5 различных приоритетов (от -2 до 2). Вторая строка показывает текущую точку выполнения нити, а третья (если она есть) - как получил управление отладчик.

Трассировка исключительных ситуаций операционной системы

В TD32 команда OS Exceptoions (в SpeedMenu области кода окна CPU) открывает диалоговое окно Specify Exception Handling, в котором вы можете задать, как Turbo Debugger должен обрабатывать исключительные ситуации операционной системы, генерируемые программой.

В блоке списка Exceptions показаны все исключительные ситуации операционной системы, обрабатываемые отладчиком. Для каждой из них вы можете задать обработку отладчиком или программой обработки исключительных ситуаций. По умолчанию они обрабатываются в Turbo Debugger. Он приостанавливает программу и активизирует окно Module или CPU, устанавливая курсор на соответствующую строку кода.

Чтобы изменить это заданное по умолчанию поведение, откройте окно Specify Exception Handling, подсветите исключительную ситуацию, которую вы хотите обрабатывать вы программе, и щелкните "мышью" на кнопке с независимой фиксацией User Program.

Если вы хотите, чтобы программа обрабатывала все исключительные ситуации операционной системы, используйте кнопку User All.

Задание пользовательских исключительных ситуаций

Поля ввода Range Low и Range High окна Specify Exception Handling позволяет задать исключительные ситуации операционной системы, определенные пользователем. По умолчанию оба эти поля устанавливаются отладчиком в 0. Введите в поле Range Low шестнадцатиричное значение, генерируемое исключительной ситуацией. Если определяется несколько исключительных ситуаций, в поле Range High введите также максимальный номер определенной пользователем исключительной ситуации.

Память и списки модулей

В TDW вы можете записать в окно Log содержимое глобальной и локальной динамической памяти или список используемых программой модулей. Окно Windows Information (доступное с помощью команды Display Windows Info в SpeedMenu окна Log) позволяет выбрать тип выводимого списка и где вы хотите его начать.

Глобальная динамически распределяемая область памяти - это память, которую Windows делает доступной для всех приложений. Эта память используется при распределении ресурсов. Чтобы увидеть список объектов данных в глобальной области, выберите в Windows Information кнопку с зависимой фиксацией Global Heap и щелкните "мышью" на OK. Объекты данных выводятся в окне Log.

Кнопка с зависимой фиксацией Start At позволяет вам выводить список с нужного места динамически распределяемой области (с начала, с конца или с места, заданного начальным описателем, устанавливаемым вызовом GlobalAlloc).

Чтобы вывести список всех задач и модулей DLL, загруженных в Windows, выберите в диалоговом окне Windows Information кнопку Module List, затем OK. Модули будут перечисляться в окне Log.

Отладка объектно-ориентированных программ

В Turbo Debugger предусмотрен ряд средств для отладки объектно-ориентированных программ С++.

Окно Hierarchy

Окно Hierarchy (открываемое командой View Hierarchy) служит для проверки иерархии объектов или классов, которая выводится в графическом виде. Область классов Область иерархии [*] Class Hierarchy 3 [^][v] Devi e Point GlowGauge Rectangle HorzArrow Device HorzBar TextWindow LinearGauge Range Point Device Range GlowGauge Rectangle Screen Parents of Device TextWindow Range VertArrow Rectangle VertBar Point Screen < >

Область порождающих классов

Это окно выводит наследование классов С++ и, в зависимости от использования в программе множественного наследования, состоит из трех областей.

Область классов

Эта область выводит в алфавитном порядке список всех классов, используемых в загруженном модуле. Справа представлена детальная информация по подсвеченному здесь классу. Для быстрого поиска класса используется средство инкрементального поиска. Если вы начнете набирать здесь имя класса, отладчик подсвечивает имя, начинающееся с набранных символов.

SpeedMenu этой области содержит две команды. Команда Inspect (или клавиша Enter) открывает для текущего класса окно Class Inspector. Команда Tree активизирует область иерархии, подсвечивая текущий класс.

Область иерархии

Здесь выводятся классы загруженного модуля и их иерархии. Базовые классы размещаются по левому полю области. Классы, наследующие из нескольких базовых классов, отмечаются звездочками (**), а все другие классы, являющиеся частью той же группы множественного наследования - одной.

Локальное меню этой области содержит две команды. Команда Inspect (или клавиша Enter) открывает для подсвеченного класса окно Class Inspector. При отладке программ С++ с множественным наследованием здесь доступна также команда Parents, включающая и выключающая вывод области порождающих классов окна Hierarchy.

Область порождающих классов

Эта область выводится только для программ с множественным наследованием и при ее разрешении. Для классов, полученных путем множественного наследования, она выводит все производные классы. SpeedMenu этой области содержит единственную команду Inspect. При ее выборе (или нажатии Enter) для подсвеченного класса выводится окно Class Inspector.

Окна Class Inspector

Эти окна позволяют вам вывести детальную информацию по классам С++. Чтобы открыть это окно, выведите окно Hierarchy, подсветите класс и нажмите Enter. [Ч] Class LinearGauge 4 [^][v] int Range::Low ^ int Range::High int Screen::MaxX v < > class Range *Range::ctr() int Range::GetValue() int Range::GetLow() int Range::GetHigh()

Данное окно содержит две области. В верхней области выводится информация о элементах данных и их типах, в нижней - о функциях-элементах и возвращаемых типах. Однако это окно не отражает данных конкретного экземпляра. Если вы хотите проверить аргументы функцию-элемента, подсветите ее и нажмите Enter. Откроется окно Function Inspector.

Если подсвеченный элемент данных представляет собой указатель на класс, то нажатие Enter открывает другое окно Class Inspector. Таким образом вы можете проверять сложные вложенные классы. Как и в случае других окон Inspector клавиша Esc закрывает текущее окно Inspector, а Alt+F3 закрывает их все.

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

Inspect В области элементов данных открывает для подсвеченного элемента данных окно Inspector. В области функций-элементов команда открывает для подсвеченной функции окно Function Inspector. Для вывода исходного кода функции позиционируйте курсор на адрес функции-элемента и нажмите Enter. Откроется окно Module.
Hierarchy Во всех областях открывает окно Hierarchy для текущего подсвеченного класса.
Show Inherited В каждой области переключается между Yes (по умолчанию) и No. При установке в Yes Turbo Debugger показывает для подсвеченного класса все функции-элементы или элементы данных, включая наследуемые. В противном случае выводятся только элементы данного класса.

Окна Object Inspector

Это окно используется для просмотра структуры и значений конкретного экземпляра класса. Чтобы открыть данное окно, поместите курсор на конкретный экземпляр класса (в окне Module) и нажмите Ctrl+I. [*] Inspecting tw 3 [^][v] @75C6:01E8 ^ Screen::MaxX 500 (Ox1F4) Screen::MaxY 512 (Ox200) v < > Screen::Convert @0000:0000 Screen::VertVtoA @0000:0000 Screen::VertAtoV @0000:0000 class TextWindow

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

SpeedMenu верхних двух областей содержат идентичные команды, только область элементов данных содержит дополнительную команду Change.

Range Позволяет вам задать диапазон выводимых элементов массива. Если подсвеченный элемент не является массивом или указателем, то команда недоступна.
Change Позволяет изменить значение подсвеченного элемента данных.
Methods Переключается между Yes (по умолчанию) и No. В состоянии Yes отладчик выводит среднюю область окна Object Inspector с перечислением функций-элементов. No отменяет вывод средней области.
Show Inherited Также переключается между Yes и No. В состоянии Yes показываются все функции-элементы, определенные в классе и наследуемые. No позволяет вывести только функции-элементы, определенные в классе.
Inspect Открывает для текущего подсвеченного элемента окно Inspector. Проверка функции-элемента открывает окно Module, где курсор позиционируется на определяющий эту функцию код.
Descend Работает аналогично команде Inspect SpeedMenu, но заменяет текущее окно Inspector. Это уменьшает число открытых на экране окон inspector.
New Expression Используется для проверки различных выражений. Данные в текущем окне Inspector заменяются данными нового вводимого выражения.
Type Cast Позволяет задавать для текущего подсвеченного элемента данные различного типа. Эта команда полезна, если идентификатор не имеет информации о типе и для явного задания типа указателей.
Hierarchy Открывает окно Hierarchy с наследованием текущего класса.

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

С помощью TD.EXE вы можете отлаживать не только обычные выполняемые файлы, но также резидентные в памяти программы (TSR) и драйверы устройств. Вы можете кроме того выполнять сам отладчик, как резидентную программу (в то время, как работаете на уровне DOS или запускаете другие программы).

Что такое резидентная программа?

Резидентными (TSR) называют такие программы, которые остаются в оперативной памяти после того, как они завершат управление. В Borland Си и С++, предусмотрена специальная функция geninterrupt, которая выдает такое программное прерывание.

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

Когда рабочая часть завершает выполнение, она вызывает функцию DOS, которая позволяет части файла .EXE оставаться резидентной в оперативной памяти после завершения выполнения программы. Рабочая часть резидентной программы знает размер резидентной части, а также ее адрес в памяти, и передает эту информацию DOS. Операционная системе DOS при этом резервирует специальный блок памяти, но может свободно записывать информацию в незащищенную часть памяти. Таким образом, резидентная часть остается в памяти, а рабочая часть может быть "затерта".

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

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

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

С помощью Turbo Debugger вы можете отлаживать драйвер клавиатуры. При этом для перемещения по отладчику пользуйтесь "мышью".

  1. При компиляции или ассемблировании резидентной программы обеспечьте наличие в ней отладочной информации.
  2. Запустите отладчик и загрузите программу.
  3. Установите точку останова в начале резидентной части кода.
  4. С помощью команды Run Run запустите рабочую часть программы.
  5. Отладьте рабочую часть программы с помощью обычных методов.
  6. Затем выйдите из TSR. Резидентная часть остается в памяти.
  7. Чтобы сделать резидентным отладчик, выберите команду File Resident. На TSR это не повлияет. После этого вы можете вернуться в DOS и вызвать TSR.
  8. В командной строке DOS нажмите оперативные клавиши вызова резидентной программы и работайте с ней как обычно.
  9. Выйдите из TSR. Теперь выполняется резидентная часть TSR, и отладчик обнаруживает точку останова. Вы можете отлаживать резидентный код.

Второй метод отладки резидентной части TSR предусматривает выполнение ее из командной строки DOS и использование окна CPU отладчика для отладки содержащей TSR области ОЗУ.

  1. Скомпилируйте программу с отладочной информацией.
  2. Используйте утилиту TDSTRIP для удаления из программы таблицы идентификаторов и помещения ее в файл .TDS.
  3. Запустите TSR из командной строки.
  4. Запустите утилиту TDMEM, которая выводит схему использования памяти. Запомните адрес сегмента, где загружена резидентная часть вашей программы.
  5. Загрузите отладчик и с помощью команды File Symbol Load загрузите таблицу идентификаторов TSR (файл .TDS).
  6. Установите в начале резидентной части TSR точку останова.
  7. Чтобы сделать отладчик резидентным, выберите команду File Resident.
  8. В командной строке DOS выполните резидентную часть TSR, нажав ее оперативную клавишу, и работайте с программой как обычно. При обнаружении точки останова отладчик приостанавливает TSR в начале резидентной части. Чтобы облегчить работу, синхронизируйте таблицу идентификаторов с кодом в памяти. Идентификаторы в таблице отстоят друг от друга на корректное число байт, но абсолютный адрес первого идентификатора не определен, так как DOS загрузила резидентную программу по адресу в памяти, отличном от того, с которым она ассемблировалась. Поэтому, чтобы найти первый идентификатор в памяти, используйте команду File Table.
  9. Используйте команду File Table Relocate для помещения первого идентификатора из таблицы идентификаторов в соответствующую ячейку памяти. Таким образом, имеющаяся информация об идентификаторах будет соответствовать вашему коду (программе). Для этого в ответ на подсказку отладчика задайте адрес сегмента Seg вашей резидентной программы, который определен с помощью утилиты TDMEM, плюс шестнадцатиричное значение 10 (для PSP размером 256 байт).

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

  10. Для перехода к сегменту оперативной памяти, где находится ваша резидентная программа, используйте команду Goto (клавиши Ctrl-G). Это можно сделать, используя адрес сегмента вашей программы TSR, за которым следует смещение 0000H, или с помощью перехода на конкретную метку вашей программы.
  11. Отладьте резидентную часть программы.

Что такое драйвер устройства?

Драйвер устройства - это набор подпрограмм, используемых операционной системой DOS для управления на нижнем уровне функциями ввода-вывода. Устанавливаемые драйверы устройств (в отличие от драйверов, встроенных в DOS) устанавливаются с помощью включения соответствующих строк, например: device = clock.sys

в файл CONFIG.SYS. Когда DOS выполняет операцию ввода-вывода для отдельного символа, она просматривает связанный список заголовков устройств, выполняя поиск устройства с соответствующим логическим именем (например, COM1). В случае драйверов блочно-ориентированных устройств, таких, как драйвер диска, DOS отслеживает, сколько установлено драйверов блочно-ориентированных устройств, и обозначает каждый из них буквой: A - первый установленный драйвер устройства, B - второй и т.д. Когда вы, например, ссылаетесь на дисковод C, DOS знает, что нужно вызвать драйвер третьего блочно-ориентированного устройства.

Связанный список двух заголовков драйвера содержит смещение двух компонентов самого драйвера устройства: подпрограмму функции и подпрограмму обработки прерывания.

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

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

Проблема при отладке драйверов устройств состоит в том, что файл .EXE отсутствует, так как для выполнения соответствующих функций драйвер должен быть загружен во время загрузки системы с помощью команды DEVICE = DRIVER.EXT, где EXT - это расширение .SYS, .COM или .BIN. Это означает, что отлаживаемый драйвер устройства уже резидентен в памяти до начала отладки. Следовательно, функции по выполнению загрузки и перемещения таблицы идентификаторов весьма полезны, поскольку они могут восстановить информацию об идентификаторах для дизассемблированного сегмента памяти (когда драйвер загружен). Как мы увидим далее, команда File Resident также очень полезна.

Отладка драйвера устройства

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

  1. Скомпилируйте драйвер с включенной отладочной информацией.
  2. С помощью утилиты TDSTRIP (см. файл TD_UTILS.TXT) выделите из драйвера устройства отладочную информацию.
  3. Скопируйте драйвер устройства на удаленную систему.
  4. Измените файл CONFIG.SYS удаленной системы, чтобы он загружал драйвер удаленной системы. Затем перезагрузите уда ленную систему.
  5. Для получения адреса драйвера загрузите на удаленной системе TDMEM.
  6. Загрузите на удаленной системе TDREMOTE.
  7. Загрузите на локальной системе отладчик, связав его с удаленной системой.
  8. Загрузите в отладчике с помощью команды File Symbol Load таблицу идентификаторов драйвера устройства.
  9. Используйте команду File Table Relocate для помещения первого идентификатора из таблицы идентификаторов в соответствующую ячейку памяти. Таким образом, имеющаяся ин формация об идентификаторах будет соответствовать вашему коду (программе). Для этого в ответ на подсказку отладчика задайте адрес сегмента Seg вашей резидентной программы, который можно определить с помощью TDMEM.
  10. Задайте в начале драйвера устройства точку останова.
  11. Выберите команду File Resident, чтобы сделать резидентным сам отладчик. Это не нарушит резидентности вашего драйвера: когда он будет выполняться в отладчике, он сам станет резидентным при загрузке удаленной системы в результате выполнения файла CONFIG.SYS. Единственная резидентной загрузки отладчика заключается в том, что вы можете перейти обратно в DOS и вызвать ваш драйвер устройства.
  12. Когда вы вернетесь снова к командной строке DOS на уда ленной системе, сделайте что-либо для активизации вашего драйвера устройства. Например, выведите информацию на со ответствующее устройство.
  13. Когда в вашей программе-драйвере встретится точка останова, инициализируется отладчик, а код вашей программы вы ведется в соответствующей точке. Теперь вы можете начать отладку вашей программы. (Кроме того, вы можете повторно войти в отладчик из DOS, дважды нажав клавиши Ctrl-Bre ak.)

Удаленная отладка

Удаленная отладка означает с соответствии со своим названием следующее: вы запускаете отладчик на одном компьютере, а отлаживаемую программу - на другом. Две системы могут соединяться через последовательный порт или через локальную сеть LAN, совместимую с NETBIOS. Удаленную отладку полезно использовать в следующих ситуациях:

В случае отладки прикладной программы Window у вас есть выбор: вы можете либо запустить на одной машине программу и отладчик для Windows (TDW), либо запустить Windows, утилиту WREMOTE и прикладную программу на одной машине, а отладчик - на другой.

Требования к программному и аппаратному обеспечению

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

Две системы должны соединяться через последовательный порт нуль-модемным кабелем. При соединении через локальную сеть потребуется программное обеспечение, совместимое с Novell Netware. программное обеспечение, совместимое с Novell Netware (версии IPX и NETBIOS 3.0 или старше).

Запуск сеанса удаленной отладки

Чтобы инициировать сеанс удаленной отладки, подготовке удаленную систему, конфигурируйте и запустите WREMOTE (драйвер удаленной отладки), запустите и конфигурируйте на локальной системе TDW и загрузите программу для отладки.

Удаленная система должна содержать следующие файлы: отлаживаемую программу и все необходимые для нее файлы, WREMOTE.EXE, WRSETUP.EXE (программу конфигурации).

Перед запуском WREMOTE с помощью WRSETUP нужно задать параметры передачи данных. Для последовательного подключения щелкните "мышью" на кнопке Serial, выберите скорость передачи (Baud Rate), выберите Desable Clock Interrupts и порт. В поле ввода Starting Directory введите каталог вашей программы. Если нужно, чтобы WREMOTE после завершения отладчика возвращала управление в Windows, установите Quit When Host Quits. По умолчанию WREMOTE использует COM1 и скорость 192000 бод. - WRSetup Turbo Debugger Setup - File Settings Help - Remote Driver Settings OK Cancel Disable clock interrupts Quit when TD quits Baud rate o 9600 Starting directory: * 19200 o 38400 o 115000 Remote type * Serial o Network Comm port Network remote name: * COM1 o COM2

При использовании связи через сеть щелкните "мышью" на кнопке с независимой фиксацией Network, в поле ввода Network Remote Name задайте имя удаленной системы (по умолчанию REMOTE), а в поле Starting Directory введите каталог программы. После закрытия окна WRSETUP установки сохраняются в файле TDW.INI.

После настройки конфигурации WREMOTE вы можете загрузить ее, щелкнув "мышью" на пиктограмме Remote Debugging или с помощью команды Windows File Run. Курсор "мыши" изменяет форму, указывая, что он ждет запуска TDW на другом конце.

Запуск TDW

После запуска на удаленной системе TDREMOTE для связи TDW с TDREMOTE его нужно правильно конфигурировать. Проще всего это сделать с помощью команды File Open (но можно использовать и Options Misceeellaneous программы TDWINST). В открывающемся диалоговом окне Load a New Program to Debug щелкните "мышью" на кнопке Session. Открывается окно Set Session Parameters. Щелкните "мышью" на кнопке Serial Remote. Затем выберите порт (Remote Link Port) и скорость передачи (Link Speed). Щелкните "мышью" на OK. (Порты систем могут быть разными, но скорость должна совпадать.)

Для конфигурации TDW на локальной сети NETBIOS запустите на удаленной системе WREMOTE, запустите TDW и выберите File Open. Открывается окно Load a New Program. Чтобы открыть окно Set Session Parameters щелкните "мышью" на кнопке Session. Выберите кнопку Network Remote и задайте имена локальной и удаленной систем (по умолчанию LOCAL и REMOTE). Затем щелкните на OK.

Инициация связи

После настройки TDW для удаленной отладки загрузите программу с помощью диалогового окна Load a New Program to Debug. TDW выводит уведомляющее сообщение. После установления связи выводится обычный экран отладчика, и команды его работают так же. Однако вывод программы на экран и ввод с клавиатуры происходит на удаленной системе.

Автоматическая передача файла

После загрузки программы TDW автоматически определяет, нужно ли пересылать программу на удаленную систему. В отношении загрузки программы в удаленную систему отладчик отличается гибкостью. Сначала он проверяет наличие программы на удаленной системе. Если программы там нет, он передает ее. Если программа на удаленной системе имеется, он анализирует дату и время копии программы на локальной системе и удаленной системе. Если копия на локальной системе более поздняя (новая), чем на удаленной, он предполагает, что вы перекомпилировали и перекомпоновали программу и передает ее по линии связи. Учтите однако, что TDW передает только файлы .EXE.

Назад | Содержание | Вперед

Copyright © CIT