Отладка программы. Как работает отладчик К чему пришли

Windows

[из методы]

Определение 9.20 Отладчик " это программный модуль, который позволяет выполнить основные задачи, связанные с мониторингом процесса выполнения результирующей прикладной программы.

Определение 9.21 Отладка " это мониторинг процесса выполнения результирующей прикладной программы.

Отладка включает в себя следующие основные возможности:

Последовательное пошаговое выполнение результирующей прикладной программы на основе шагов по машинным командам или по операторам входного языка;

Выполнение результирующей программы до достижения ею одной из данной точек останова (адресов останова);

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

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

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

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

Появление интегрированных сред разработки;

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

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

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

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

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

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

Многие их функции интегрированы с функциями текстовых редакторов исходных текстов, входящих в состав систем программирования.

Отла́дчик или деба́ггер (англ. debugger) является модулем среды разработки или отдельным приложением, предназначенным для поиска ошибок в программе. Отладчик позволяет выполнять пошаговую трассировку, отслеживать, устанавливать или изменять значения переменных в процессе выполнения программы, устанавливать и удалять контрольные точки или условия остановки и т. д.

Список отладчиков

AQtime - коммерческий отладчик для приложений, созданных для.NET Framework версии 1.0, 1.1, 2.0, 3.0, 3.5 (включая ASP.NET приложения), а также для Windows 32- и 64-битных приложений.

DTrace - фреймворк динамической трассировки для Solaris, OpenSolaris, FreeBSD, Mac OS X и QNX.

Electric Fence - отладчик памяти.

GNU Debugger - отладчик программ от проекта GNU.

IDA - мощный дизассемблер и низкоуровневый отладчик для операционных систем семейства Windows и GNU/Linux.

Microsoft Visual Studio - среда разработки программного обеспечения, включающая средства отладки от корпорации Microsoft.

OllyDbg - бесплатный низкоуровневый отладчик для операционных систем семейства Windows.

SoftICE - низкоуровневый отладчик для операционных систем семейства Windows.

Sun Studio - среда разработки программного обеспечения, включающая отладчик dbx для ОС Solaris и GNU/Linux, от корпорации Sun Microsystems.

Dr. Watson - стандартный отладчик Windows, позволяет создавать дампы памяти.

TotalView - один из коммерческих отладчиков для UNIX.

WinDbg - бесплатный отладчик от корпорации Microsoft.

Рассмотрим процесс отладки программы, решающей уравнение вида АХ+В=0 без сохранения данных в файле (постановку задачи см. в гл. 3). Будем считать, что форма содержит только элементы, помещенные на вкладке "Данные" (рис. 3.5), и имеет вид (рис. 8.6). Имена текстовых окон для ввода коэффициентов TBA и TBB, а также имя метки для вывода корня LBX, помещены внутри графических изображений указанных объектов. Имена СВ1, СВ2 и СВ3 присвоены командным кнопкам. Имена данных А,В,Х для коэффициентов a,b и корня Х соответственно. Входные и выходные данные


ВХОД

Рис. 8.7. Р-граф программы


Таблица 8.1 Условные обозначения к рис. 8.7 Условия Действия Процедура InDan() Реализуется объектами управления формой То же То же
Нажата кнопка завершения программы Нажата кнопка СВ2 "Корень" Нажата кнопка СВ1 "Очистить" Введен символ, который можно рассматривать как допустимый при вводе чисел Инициализация данных (присвоение им начальных значений) Нажатие доступной кнопки, щелчок мыши или ввод символа Выбор объекта ТВА Выбор объекта ТВВ
Обозначение Выход Корень Очистить Введен символ числа Init Ввод команды Активизация TBА Активизация TBB
Продолжение табл. 8.1 Реализующая процедура (функция) Функция MessX и оператор присваивания Реализуется объектом Text Box Процедура ProgEnd Состояния
Соответствующее действие или условие Расчет корня уравнения и вывод в метку LBX Добавление символа в ТВА.Техt Добавление символа в ТВВ.Техt Завершение программы Начата работа программы, на экране видна форма, ожидается ввод команды или символа На экране видна форма, введена команда Вычислены коэффициенты и корень, сформировано сообщение о корне В буфер клавиатуры введен произвольный символ
Обозначение LBX.Caption=MessX Simb® TBA.Text Simb® TBB.Text Зав. прог Вход, 1

Структура программы



Имя модуля, объекта, секции Содержание
OpDan Описание данных a,b,x Public a as single: Public b as single: Public x as single
Форма Form1
Секция General Sub InDan() "Инициализация данных I=MsgBox("Инициализируются данные", vbOkOnly,"") End sub Sub NullDan() "Очистка формы и данных I=MsgBox("Очистка формы и данных", vbOkOnly,"") End sub Function MessX() "Вычисление корня I=MsgBox("Вычислено а=10, b=5, x=-2", vbOkOnly,"") MessX= "-2" End function Sub EndProg() "Завершение программы I=MsgBox("Программа завершена", vbOkOnly, "") End sub
Form1 Sub Form1_Load() "Загрузка формы Call InDan End sub Sub Form1_Unload "Выгрузка формы из памяти Call EndProg() End sub
CB1 Sub CB1_Click() "Нажатие кнопки Очистить Call NullDan End sub
CB2 Sub CB1_Click() "Нажатие кнопки Корень LBX.Caption=MessX() End sub
CB3 Sub CB3_Click() "завершение программы Call EndProg End End sub

Рис. 8.8. Структура программы

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

Таблица 8.2

Карта тестирования интерфейса

Название теста Действия программиста Реакция программы
Пуск Запуск программы Появление на экране формы и окна с сообщением "Инициализируются данные"
Инициализация ТВА Курсор ставится в ТВА
Инициализация ТВА Курсор ставится в ТВВ
Ввод символов Нажимать алфавитно-цифровые клавиши К содержимому активного текстового окна добавляются вводимые символы. При нажатии клавиши "Забой" правый символ в окне стирается
Очистка Появляется сообщение "Очистка формы"
Расчет Появляется сообщение "Вычислено а=10, b=5, x= -2"
Завершение программы

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

Sub InDan() "Инициализация данных OpDan.a=0: OpDan.b=0: OpDan.x=0 TBA.Text="": NBB.Text="" LBX.Caption="" I=MsgBox("Инициализируются данные"+str(OpDan.a)+" "+str(OpDan.b) +" "+str(OpDan.x), vbOkOnly,"") end sub Рис. 8.9. Текст процедуры InDan() в период отладки Начинаем с процедуры InDan. Назначение процедуры – обнуление данных и очистка формы. Текст процедуры в период отладки приведен на рис. 8.9. В результате тестирования процедуры должны быть достигнуты результаты: переменные a,b,x модуля OpDan должны принять значение нуль, текстовые окна и метка LBX должны быть пустыми.
Sub NullDan() "Очистка формы и данных OpDan.a=0: OpDan.b=0: OpDan.x=0 TBA.Text="": NBB.Text="" LBX.Caption="" I=MsgBox("Очистка формы и данных" +str(OpDan.a)+""+str(OpDan.b)+"" +str(OpDan.x), vbOkOnly,"") End sub Рис. 8.10. Текст процедуры NullDan() в момент отладки Далее отлаживаем процедуру очистки формы. Ее текст в момент отладки приведен на рис. 8.10. Текст процедуры можно скопировать из процедуры InDan, т.к. она выполняет аналогичное назначение. В данном случае вполне можно вместо двух процедур иметь одну. Результат отладки процедуры – нулевые значения данных, описанных в модуле OpDan и пустые текстовые окна и метка LBX.
Процесс отладки обеих процедур одинаков. Запустив программу на исполнение можно по сообщениям проконтролировать правильность выполнения процедур. В случае появления неверных результатов можно перейти в пошаговый режим и, наводя указатель мыши на имена данных, контролировать результаты вычислений. Возможно и применение пошагового режима с включением окна Watches, в которое следует добавить имена перечисленных выше переменных.
Function MessX() "Вычисление корня Dim S as String OpDan.a=val(TBA.Text) OpDan.b=val(TBB.Text) If a<>0 then S=str(-b/a) Elseif ((a=0) and (b=0)) then S="Неопределенный корень" Elseif ((a=0) and (b=0)) then S="Корень не существует" End if MessX= S TBA.Text = str(OpDan.a) TBB.Text = str(OpDan.b) LBX.Caption = str(OpDan.b) I=MsgBox("Вычислены а, b, x", vbOkOnly,"") End function Рис. 8.11. Текст функции MessX в момент отладки Отладка функции MessX (рис. 8.10) выполняется в пошаговом режиме с установкой курсора на первый оператор текста функции. Целесообразно включить окна Watches и Locals и добавить в первое из них имена переменных из модуля OpDan, а во второе будет выводиться значение переменной S. Для отладки используются три набора данных: · a=10.6, b=31.8; · a=0, b=0; · a=0, b=10. Программа запускается командой "Debug/Run to Cursor". Наборы данных вводятся через окна формы. Выполнение программы прерывается на операторе OpDan.a=val(TBA.Text). Далее, применяя команду "Debug/Step Into", выполняем программу в пошаговом режиме и отслеживаем значения переменных.

Первый набор данных инициирует выполнение оператора S=str(-b/a) , второй – оператора S="Неопределенный корень" , третий – оператора S="Корень не существует" . В первом случае значение корня равно (– 3). Вычисленные значения коэффициентов и корня можно наблюдать на форме в текстовых окнах и метке LBX.

Тестирование завершенного кода программы выполняется в соответствии с картой тестирования программы (табл. 8.3).

Таблица 8.3

Карта тестирования программы

Название теста Действия программиста Реакция программы
Пуск Запуск программы Появление на экране формы и окна MsgBox с сообщением "Инициализируются данные"
Инициализация ТВА "Щелчок" мышью по текстовому окну TBA Курсор ставится в ТВА
Инициализация ТВА "Щелчок" мышью по текстовому окну TBB Курсор ставится в ТВВ
Ввод набора данных Ввести набор данных · a=10.6, b=31.8; · a=0, b=0; · a=0, b=10.2 В активном текстовом окне (ТВА или ТВВ) появляются вводимые данные. Должна действовать клавиша "Забой2
Очистка "Щелчок" мышью по кнопке "Очистить" Появляется сообщение "Очистка формы", далее очищаются текстовые окна и метка LBX
Расчет "Щелчок" мышью по кнопке "Корень" Появляется сообщение "Вычислены а, b, x", на форме появляются вычисленные значения коэффициентов и корней
Возврат Повторить один за другим тесты "Очистка", "Ввод данных" и "Расчет" Очищается форма, вводятся данные, вычисляется корень, выводятся коэффициенты (повторно) и корень
Завершение программы "Щелчок" мышью по кнопке "Выход" или по кнопке "Х" Появляется сообщение "Программа завершена"

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

8.2. Создание инсталляционного комплекта
программного средства

После завершения работы по отладке программного средства достаточно легко получить ее исполняемый код. Он может быть построен в двух формах: как независимый исполняемый код и как P-cod (псевдокод), для исполнения которого необходим файл, входящий в комплект поставки Visual Basic и обеспечивающий выполнение программы. Первый код длиннее, но может работать без всяких добавок системы Visual Basic, второй код короче, но требует наличия указанного файла. Обычно предпочитают первый вариант. Способ компиляции указывается в окне "Свойства проекта".

Для построения инсталляционного комплекта (дистрибутива) запускается специальное приложение (Application SetupWizard для Visual Basic 5 и Package and Deployment Wizard для Visual Basic 6). Процесс создания дистрибутива происходит в диалоговом режиме в несколько шагов. Общий вид окон приложения (мастера) Application Setup Wizard приведен на рис. 8.12.

а) б) Рис. 8.12. Окна приложения Application SetUp Wizard "Выбор проекта и настройка" (а) и "Метод распространения" (б) В первом окне Application Setup Wizard выводятся различные сообщения, в частности, о назначении программы и основных действиях, выполняемых ею. Это окно здесь не показано. Следующим шагом является выбор проекта для создаваемого инсталляционного комплекта и настройка работы приложения. Для этой цели служит окно "Выбор проекта и настройка" (рис. 8.12,а). В этом окне устанавливается путь к файлу проекта и опции, позволяющие открыть программу установки с созданием или без создания зависимого файла, создать комплект поставки для распространения через Internet и просто создать зависимый файл. В следующем окне "Метод распространения" (рис. 8.12,б) выбирается способ размещения комплекта на носителях: на одной дискете, в одном каталоге на жестком диске для копирования на CD-Rom или в нескольких каталогах с именами Disk1, Disk2, … для создания комплекта дискет.
а) б) Рис. 8.13. Окна приложения Application Setup Wizard "Каталог-приемник" (а) и "Итоговый файл" (б) В следующем окне делается выбор каталога-приемника, который будет содержать создаваемый инсталляционный комплект. В этом окне указывается диск и путь к файлам инсталляционного комплекта. Дерево папок позволяет выбрать нужный путь к указанным файлам. В следующем окне мастера указываются серверные и локальные компоненты ActiveX. Это окно на рисунке не показано. В предпоследнем окне приложения "Итоговый файл" (рис. 8.13,б) показаны файлы, присоединяемые к файлам проекта. Как правило, это библиотеки *.dll. Приложение Application Setup Wizard автоматически составляет список файлов, которые необходимо добавить в комплект. Имеется возможность добавить свои файлы, кроме добавляемых приложением автоматически. В последних двух окнах выводятся сообщения о том, что комплект собран, и работа приложения завершена. Эти окна

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

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


Тяжело быть отладчиком...

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

Конечно, поскольку сейчас множество всяких различных языков программирования, то и отладчики для каждого из них свои. И, естественно, для разных категорий этих языков имеются различия в работе отладчиков: например, отладчик программ на интерпретируемом Ruby будет работать иначе, чем для компилируемого в байт-код языка Java, а отладчик для Java, в свою очередь, будет иметь отличия от отладчика Visual C++.

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


Отладчики для Windows: два вида

Существуют два принципиально разных вида отладчиков под Windows. Думаю, с первыми сталкивались все, когда программировали на Delphi (не программировали на нём? С трудом верится. На чём же вы программировали в школе и на младших курсах?). Это отладчики пользовательских приложений. Их немало, и они существуют как по отдельности, так и (особенно, кстати, часто) в составе интегрированных сред разработки приложений. Среди отладчиков, распространяемых как отдельные программные продукты, традиционно выделяют OllyDbg, и о нём я когда-то писал в "Компьютерных вестях".

Второй вид отладчиков - это отладчики ядра операционной системы. Они встречаются и используются реже и по своему устройству значительно отличаются от отладчиков пользовательских приложений. Самый известный, и, одновременно, самый лучший из отладчиков ядра - это SoftIce. Возможно, вы о нём не только слышали, но даже пользовались.

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


Отладчик пользовательских приложений

Отладчик пользовательских приложений устроен проще, поскольку самую чёрную и грязную работу берёт на себя операционная система. В Windows есть специальные программные интерфейсы, которые предназначены для отладки приложений пользовательского уровня - называются они Windows Debugging API. Именно отладочными API пользуются все отладчики, которые встроены в популярные интегрированные среды разработки для Windows.

Для того чтобы отладка началась, отладчик должен запустить отлаживаемый процесс специальным образом - таким, чтобы система знала, что этот процесс будет находиться под отладкой. После этого начинается цикл отладки: программа выполняется до наступления определённого события, которое так и называется - отладочное событие, или debug event. При этом цикл отладки запускается в отдельном потоке, чтобы предотвратить зависание отладчика.

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

Итак, отладочное событие произошло, и дальше надо каким-то образом узнать, как это связано с текстом программы. Это возможно только если в саму программу включена специальная отладочная информация - таблица отладочных символов. Она содержит в себе информацию о соответствии между адресами и именами функций, типов данных, номерами строк кода. Именно благодаря им возможна та отладка, с которой знаком каждый Windows-программист. Таблицы символов имеют разные форматы, а потому не всегда возможно отладить программу, скомпилированную компилятором одного разработчика, с помощью отладчика от другого производителя. Но, правда, самый распространённый формат всё же можно указать - это PDB (Program Database), и разработан он, естественно, корпорацией Microsoft.

Итак, если отладочная таблица символов имеет формат PDB, то можно воспользоваться специальным инструментом от корпорации Microsoft - символьным отладочным процессором. Когда-то он входил в ядро системы и назывался Imagehlp.dll, но уже давным-давно был выделен в отдельную библиотеку. Символьный процессор позволяет находить по заданному адресу ближайшую открытую функцию или глобальную переменную, а также номер строки и название файла с исходным текстом, в котором эта строка находится. Поддерживаются и обратные операции, например, поиск адреса функции по её имени.

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

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


Отладчик ядра

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

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

В современных процессорах архитектуры Intel x86 имеются специальные отладочные регистры (и в стареньком 368-м, и в более новых моделях процессоров их всего восемь, они именуются как DR0-DR7). Эти регистры позволяют отладчику ставить контрольные точки на чтение и запись памяти, а также на порты ввода-вывода. В общем виде всё выглядит именно так, и я не думаю, что стоит сейчас расписывать подробно, за что отвечает каждый из отладочных регистров, какими прерываниями реализуются точки останова и давать прочую подобную информацию. Лучше расскажу о конкретных существующих отладчиках ядра для Windows.

Ну, во-первых, это отладчик, встроенный в само ядро операционной системы. Он есть во всех ОС линейки NT, начиная с Windows 2000. Это часть файла NTOSKRNL.EXE, и включить его можно, задав опцию "/Debug" для операционной системы в BOOT.INI. Этот отладчик нуждается в нуль-модемном соединении и втором компьютере с такой же ОС.

Есть ещё один отладчик ядра от Microsoft - WinDBG. Строго говоря, это не отладчик ядра, а гибридный отладчик, который можно использовать и для отладки приложений уровня пользователя. Он, в отличие от отладчика, встроенного в ядро, имеет графическую оболочку, а потому пользоваться им проще. Этот отладчик также поддерживает специальные расширения, которые могут пригодиться при решении некоторых задач отладки. Но и он для отладки ядра требует два компьютера.

Однако существует отладчик ядра, который может осуществлять отладку на одном-единственном компьютере. Это SoftIce. При этом SoftIce умеет отлаживать и прикладные программы. Использование этого отладчика для пользовательских программ оправдано, например, в случае отладки систем реального времени, привязываемых к системному таймеру. Если выполнять отладку с помощью обыкновенного отладчика, то результат может оказаться неправильным даже при правильной работе программы, а SoftIce остановит и программу, и таймер. Это полезно при отладке многопоточных приложений. Ко всему прочему, SoftIce имеет очень, очень хорошо развитые средства вывода информации обо всех потоках в системе, о синхронизации потоков для многопоточных приложений, информации о handle"ах... Единственный минус этого отладчика - его сложность для прикладного программиста. Но из отладчиков ядра это самый простой и эффективный.


Для самых любознательных

Сейчас, конечно, разговор об отладчиках для Windows-приложений не так актуален, как ещё лет десять назад. Весь мир заинтересовался Интернетом, и основными пользователями SoftIce стали крякеры, неутомимые труженики на ниве пиратства. Тем не менее, это не так уж плохо. Общение с SoftIce"ом, несомненно, развивает человека в плане знаний о компьютере, хотя, конечно, если общаться только с отладчиками и не общаться с живыми людьми, возможны некоторые побочные эффекты. Ну, об этом, я думаю, все и так догадываются.

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

Итак, если вам хочется создать собственный отладчик, то сначала стоит ознакомиться с материалами на эту тему. На мой взгляд, самым лучшим пособием для начала будет книга Джона Роббинса "Отладка Windows-приложений". Она уже старая, 2001-го года издания, но информация, изложенная в ней, актуальна и сейчас, поскольку имеет общий, даже в некотором роде фундаментальный характер. В этой книге есть примеры написания отладчиков для Windows, кроме того, она пригодится вам, если вы программируете на C++ и хотите лучше разобраться в обработке исключений. Собственно, именно из этой книги я и почерпнул сведения об отладчиках, изложенные в статье. Если же найти эту книгу не получится (всё-таки, она уже довольно старая), есть несколько адресов, которые могут вам пригодиться. Первый - вот такой: www.xakep.ru/post/19158/default.asp . Эта статья из журнала "Хакер" несколько подробнее рассказывает об отладчиках ядра, чем это сделал я, а кроме того, в ней приведён код простейшего отладчика. А по адресу kalashnikoff.ru/Assembler/issues/016.htm можно узнать о том, как написать DOS-отладчик. Но, конечно, лучше всего читать MSDN и попутно найти какой-нибудь отладчик с открытыми исходными текстами, чтобы в нём разобраться. Ну и, конечно, если вы взялись за написание отладчика, то успехов вам в этом нелёгком деле!