Тепер, після опису точок переривання і символьних машин, можна пояснити, як отладчики реалізують три чудові операції - Step Into, Step Over і Step Out. Вони не реалізовані в WDBG, тому що я хотів сконцентруватися на основних частинах відладчика. Ці функції працюють в рамках двох спеціальних представленій1 налагоджують програму, які дозволяють відстежувати поточну виконувану рядок або команду.
Всі ці операції (Step Into, Step Over і Step Out) працюють з одноразовими точками переривання, які, як ви пам'ятаєте з попередніх розділів, є точками переривання, які можна скидати отладчиком після того, як вони спрацьовують. Під час обговорення пункту меню Debug Break (див. Вище) був розглянутий інший випадок, в якому відладчик використовує одноразові точки переривання для зупинки обробки.
Операція Step Into працює по-різному, в залежності від того, на якому рівні виконується налагодження: на початковому або на рівні дизассемблирования. При налагодженні на вихідному рівні відладчик повинен орієнтуватися на одноразові точки переривання, тому що один рядок мови високого рівня переводиться в одну або декілька рядків мови асемблера. При перекладі CPU в покроковий режим буде відбуватися покрокове виконання індивідуальних машинних команд, а не рядків вихідного коду.
Source view (подання до вигляді рядків вихідного коду) і disassembly view (подання до вигляді кодів дизассемблера у вікні Disassembly). - Пер.
Обробка операцій Step Into, Step Over і Step Out здається досить простий, але є одна особливість, яку слід розглянути. Що робити, якщо (в відладчик, створюваному для управління цими операціями) вже встановлені точки переривання one-shot для цих операцій, а перед ними спрацьовує регулярна точка переривання? Як розробник відладчика, ви маєте дві можливості. Перша - залишити тільки точки переривання one-shot (щоб тільки вони і спрацьовували). Інша можливість - видаляти точки переривання one-shot, коли відладчик повідомляє вас про те, що спрацювала регулярна точка переривання. Отладчик Visual C ++ використовує останню можливість.
Цікава проблема розробки WDBG
Взагалі у мене було мало неприємностей при розробці WDBG. Однак настав час обговорити одну, на мій погляд, досить цікаву проблему. При роботі з отладчиком Visual C ++ вікно Output показує повні шляху до завантаженим програмним модулям. Оскільки потрібно забезпечити WDBG максимальним набором функціональних можливостей, в ньому продубльована ця функція відладчика Visual C ++. Але зробити це виявилося непросто.
Наведене нижче визначення структури LOAD_DLL_DEBUG_INFO (вона передається в відладчик при отриманні повідомлень LOAD_DLL_DEBUG_EVENT) містить поле ipimageName. яке, ймовірно, повинно зберігати ім'я завантаження модуля. Це так і є, але жодна з операційних систем Win32 ніколи правильно не заповнює це поле при його зчитуванні в програму.
typedef struct _LOAD_DLL_DEBUG_INFO
Оскільки при отриманні повідомлення LOAD_DLL_DEBUG_EVENT. образно кажучи, модуль завантажується в символьну машину DBGHELP.DLL. то мені здавалося, що після завантаження модуля (в пам'ять) легко можна відшукати його повне ім'я. API-функція SymGetModuieinfo отримує (через відповідний параметр) показану нижче структуру IMAGEHLP_MODULE. де є місце для повного імені модуля (див. поле ModuleName [32]).
Насправді все, мабуть, навпаки: це символьний машина завантажує символьну інформацію модуля до відповідного символьний файл (в даному випадку - в DBG-файл). - Пер
typedef struct _IMAGEHLP_MODULE
Дивна річ: коли функція SymGetModuieinfo повертає символьну інформацію модуля, то замість імені модуля або повертається ім'я символьного DBG-файлу, або нічого не повертається (т. Е. Ім'я модуля в яку повертатимуть інформації повністю пропускається). Така поведінка може здатися дивним, але тільки на перший погляд. Коли була отримана • структура LOAD_DLL_DEBUG_INFO. її перший член (типу hFile) був правильним, і тоді була викликана функція SymLoadModuie з дескриптором того ж типу (hFile). Оскільки я ніколи не завантажував в символьну машину DBGHELP.DLL повне ім'я файлу, вона просто заглядала у відкритий файл, позначений дескриптором hFile. знаходила в ньому зневадження і зчитувала її. У символьній машини ніколи не було необхідності знати повне ім'я файлу.
Отримати ж потрібно повне ім'я завантаженого модуля. Спочатку я думав, що міг би використовувати сам дескриптор файлу, щоб отримати доступ до експортної секції модуля і повідомити знайдене там ім'я модуля. Крім того, модуль міг бути перейменований, і його ім'я в експортній секції було б неправильним. Це міг бути ЕХЕ - або DLL -модуль, який не містить списку експортованих модулів. І навіть якщо б якось вдалося знайти правильне ім'я модуля, його повне ім'я (шлях) було б недоступно.
Загальне питання налагодження
Чому я не можу входити в системні функції або встановлювати точки переривання в системній пам'яті Windows 98?
Отже, ви хочете написати власний відладчик?
Перший крок, який потрібно зробити після розгляду WDBG. - отримати чудову книгу (Джонатан Розенберг "Як працюють отладчики"). Хоча там не представлені вихідний код відладчика, це - чудове введення і обговорення реальних проблем, з якими програміст зіткнеться при написанні відладчика.
Необхідно детально познайомитися з форматом РЕ і конкретним CPU. на якому ви працюєте. Супроводжуючий компакт-диск містить PECOFF.DOC. найостаннішу специфікацію РЕ-файлів від Microsoft. Детальніше можна вивчати CPU по посібникам Intel CPU, доступним на www.intel.com.
Написання дизассемблера найкраще почати зі довідкових посібників фірми Intel. Вони містять всю необхідну інформацію по командам і кодами операцій, а також повну карту кодів операцій, яку потрібно знати для включення відповідних чисел в команди. Вихідний код декількох дизассемблеров можна знайти в Інтернеті. Перш ніж приступити власне до написання, слід вивчити вихідні коди декількох дизассемблеров, щоб отримати основні ідеї і подивитися, як інші фахівці справлялися з цим завданням.
Як вже говорилося, символьна машина DBGHELP.DLL достатня для деяких чудових допоміжних налагоджувальних утиліт, але не достатня для реального відладчика. Ви можете завжди зайнятися зворотного розробкою формату PDB-файлів, а ми все можемо сподіватися, що Microsoft коли-небудь відкриє доступ до PDB-файлів.
WDBG: що робити далі?
Після установки відладчик WDBG працює так, як було задумано. Однак його можна поліпшити за багатьма напрямками. Нижче перераховані деякі ідеї вдосконалення WDBG. Якщо ви займетеся розширенням WDBG. повідомте мені про це. Крім того, як уже говорилося в главі. чудовою ілюстрацією професійних здібностей програміста є приклади власного коду (вельми корисні, скажімо, і для робочих інтерв'ю). Якщо ви додаєте якусь істотну властивість до WDBG. то потрібно показати це!
- Можна зайнятися інтерфейсом користувача (UI) WDBG -отладчіка. Перше удосконалення, яке можна здійснити - поліпшити реалізацію цього інтерфейсу. Інтерфейс вже містить всю необхідну інформацію; ви повинні тільки спроектувати кращі способи її подання.
- Сам WDBG підтримує тільки прості, позиційні точки переривання (location breakpoints). За допомогою BREAKPOINT.H і BREAKPOINT.CPP можна додати цікаві додаткові види точок переривання, такі як точки переривання з лічильником пропусків (skip count breakpoints) або точки переривання виразів (expression breakpoints), для яких переривання відбувається, тільки якщо позначене ними вираз істинний. Переконайтеся, що ви отримуєте нові точки переривання за допомогою функції CLocationBp (завдяки якій ви отримуєте се- \ ріалізованний код і не повинні нічого змінювати в WDBG).
- Ви повинні бути здатні без великих зусиль розширити WDBG. щоб підтримати налагодження множинних процесів (multiple process debug-> ging). Більшість інтерфейсів побудовані для роботи за схемою ідентифікації процесу, так що потрібно тільки простежити, з яким процесом ви працюєте під час повідомлення про налагодження.
- Інтерфейс WDBG побудований так, щоб дозволити швидко перейти до віддаленої налагодженні і різним CPU, залишивши роботу головної частини інтерфейсу приблизно такий же. Напишіть динамічні бібліотеки вилученого налагодження і розширте WDBG так, щоб дозволити користувачеві вибирати, де виконувати налагодження: на місцевій або на віддаленій машині.
- Нарешті, щоб зробити WDBG-відладчик дійсно корисним, ви завжди можете написати кращий дизассемблер і символьну машину для налагоджувальних символів формату С7!
У цьому розділі наведено короткий огляд механізмів функціонування отладчиков. Вивчаючи різні інструментальні засоби, можна істотно поліпшити їх використання. Тут був представлений Win32 Debugging API (оцінний API 32-розрядних операційних систем Windows) і деякі підтримують системи, такі, наприклад, як символьні машини. Ви також дізналися про існування деяких інших отладчиков (крім відладчика Visual C ++). Нарешті, наведено приклад повного відладчика - WDBG, який добре ілюструє роботу відладчика.
Чи знаєте Ви, що діаграма компонентів, Component diagram - це метод об'єктно-орієнтованого проектування, що описує особливості фізичного представлення системи. Діаграма компонентів дозволяє визначити архітектуру розроблюваної системи, встановлюючи залежності між компонентами.
НОВИНИ ФОРУМУ
Лицарі теорії ефіру