Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Сабуров С.В. - Язык программирования C и C++ - 2006

.pdf
Скачиваний:
312
Добавлен:
13.08.2013
Размер:
1.42 Mб
Скачать

Отладчик Turbo Debugger

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

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

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

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

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

Окно Hierarchy

Окно Hierarchy (открываемое командой View Hierarchy) служит для проверки иерархии объектов или классов, которая выводится в графическом виде.

327

Отладчик Turbo Debugger

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

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

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

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

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

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

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

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

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

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

328

Отладчик Turbo Debugger

Окна Class Inspector

Эти окна позволяют вам вывести детальную информацию по классам С++. Чтобы открыть это окно, выведите окно Hierarchy, подсветите класс и нажмите Enter.

[Ч]

Class

LinearGauge

4

int

Range

::Low

 

int

Range

::High

 

int

Screen

::MaxX

 

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 для текущего подсвеченного класса.

329

Отладчик Turbo Debugger

Show Inherited

Вкаждой области переключается между Yes (по умолчанию)

иNo. При установке в Yes Turbo Debugger показывает для подсвеченного класса все функции элементы или элементы данных, включая наследуемые. В противном случае выводятся только элементы данного класса.

Окно Object Inspector

Это окно используется для просмотра структуры и значений конкретного экземпляра класса. Чтобы открыть данное окно, поместите курсор на конкретный экземпляр класса (в окне

Module) и нажмите Ctrl+I.

[*]

Inspecting tw

 

3

@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

330

Отладчик Turbo Debugger

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 или запускаете другие программы).

331

Отладчик Turbo Debugger

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

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

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

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

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

332

Отладчик Turbo Debugger

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

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

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

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

Запустите отладчик и загрузите программу.

Установите точку останова в начале резидентной части кода.

С помощью команды Run Run запустите рабочую часть программы.

Отладьте рабочую часть программы с помощью обычных методов.

Затем выйдите из TSR. Резидентная часть остается в памяти.

Чтобы сделать резидентным отладчик, выберите команду File Resident. На TSR это не повлияет. После этого вы можете вернуться в DOS и вызвать TSR.

В командной строке DOS нажмите оперативные клавиши вызова резидентной программы и работайте с ней как обычно.

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

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

● Скомпилируйте программу с отладочной информацией.

333

Отладчик Turbo Debugger

Используйте утилиту TDSTRIP для удаления из программы таблицы идентификаторов и помещения ее в файл .TDS.

Запустите TSR из командной строки.

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

Загрузите отладчик и с помощью команды File Symbol Load загрузите таблицу идентификаторов TSR (файл

.TDS).

Установите в начале резидентной части TSR точку останова.

Чтобы сделать отладчик резидентным, выберите команду

File Resident.

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

Используйте команду File Table Relocate для помещения первого идентификатора из таблицы идентификаторов в соответствующую ячейку памяти. Таким образом, имеющаяся информация об идентификаторах будет соответствовать вашему коду (программе). Для этого в ответ на подсказку отладчика задайте адрес сегмента Seg вашей резидентной программы, который определен с помощью утилиты TDMEM, плюс шестнадцатеричное значение 10 (для PSP размером 256 байт). Дизассемблированные из памяти операторы синхронизированы с информацией из таблицы

334

Отладчик Turbo Debugger

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

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

Отладьте резидентную часть программы.

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

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

device = clock.sys

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

B — второй и т.д. Когда вы, например, ссылаетесь на дисковод C, DOS знает, что нужно вызвать драйвер третьего блочно ориентированного устройства.

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

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

335

Отладчик Turbo Debugger

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

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

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

DEVICE = DRIVER.EXT

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

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

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

Скомпилируйте драйвер с включенной отладочной информацией.

С помощью утилиты TDSTRIP выделите из драйвера устройства отладочную информацию.

Скопируйте драйвер устройства на удаленную систему.

336

Соседние файлы в предмете Программирование на C++