Налагодження програм користувача в Tubro Pascal h2>
Думаю,
ви не раз стикалися з тим, що програма відмовлялася працювати так, як
треба. Часто ці помилки призводять до того, що рішення задачі заходило в глухий кут.
Тут і приходять на допомогу великі засоби налагодження програм Turbo Pascal.
Зазвичай ці кошти використовуються рідко, а даремно. Уміла налагодження програми
дозволяє уникнути багатьох підводних каменів і створювати ідеальні програми. p>
Введення. h2>
Turbo
Pascal пропонує сверхусовершенствованную середовище, з автоматичним управлінням
проектом, модульної організацією програм, високою швидкістю компіляції, з
легко використовуваними оверлеями. Але навіть використовуючи всі ці надані
кошти, програми користувача можуть містити помилки, які призводять до
неправильній роботі програми. p>
В
допомога користувачу Turbo Pascal надає кошти, необхідні для
налагодження його програми, що сприяють усуненню всіх помилок в програмі, її
ретельному тестування та виконання. Turbo Pascal дозволяє легко визначати
місце розташування помилок під час компіляції та під час виконання програми, а
також дозволяє включати або вимикати автоматичний контроль помилок під час
виконання програми. p>
Особливо
важливо те, що Turbo Pascal має потужний і гнучкий відладчик вихідного рівня,
який дозволяє користувачеві виконувати програму порядково, переглядати
вираження і модифікувати змінні в міру необхідності. Усунення несправностей вбудований в
інтегроване середовище розробки (IDE) Turbo Pascal; користувач може
редагувати, компілювати і налагоджувати програму навіть не виходячи з Turbo
Pascal. Для великих або складних програм, які вимагають використання всього
діапазону засобів налагодження від машинної мови до обчислення виразів Паскаля,
Turbo Pascal повністю підтримує автономний відладчик фірми Borland, Turbo
Debugger. p>
Типи помилок. h2>
Існує
три основних типи програмних помилок: помилки часу компіляції, помилки часу
виконання та логічні помилки. p>
Помилки
компіляції. p>
Помилки
компіляції або синтаксичні помилки зустрічаються, коли забувають оголосити
змінну, передають помилкове кількість параметрів процедури, при призначенні
дійсного значення цілочисельний змінної. Це означає, що
записуються оператори, які не узгоджуються з правилами Паскаля. p>
Turbo
Pascal не закінчить процес компіляції програми користувача (генерацію
машинного коду), поки всі синтаксичні помилки не будуть видалені. Якщо Turbo
Pascal виявить синтаксичну помилку під час компіляції програми, він
зупиняє компіляцію, входить у вихідний текст, вказує місце розташування
помилки позиціонуванням курсору і виводить повідомлення про помилку у вікно Edit. Як
тільки користувач виправить помилку, він зможе почати процес компіляції знову.
p>
Якщо
використовується версія командного рядка (TPC.EXE), Turbo Pascal буде виводити
помилковий оператор, номер рядка та повідомлення про помилку. Потім користувач
може увійти в будь-який використовуваний ним редактор, знайти задану рядок, виправити
помилку і переконфігурувати програму. Для додаткової інформації про
повідомленнях про помилки див. Додаток А в Посібнику програміста. p>
Помилки
виконавчі. p>
Інший
тип помилок - помилки часу виконання програми або семантичні помилки. Вони
зустрічаються, коли користувач вибирає синтаксично коректну програму,
яка намагається зробити щось заборонене під час її виконання,
наприклад, відкриває неіснуючий файл для введення або виробляє ділення на 0.
У цьому випадку Turbo Pascal виводить на екран таке повідомлення про помилку:
Runtime error # # at seg: ofs (Помилка виконання # в сегменті: зсув) і
зупиняє виконання програми користувача. p>
При
використанні інтегрованого середовища Turbo Pascal визначає місце розташування
помилки виконання автоматично, здійснюючи перехід у вікно редагування для
відповідного вихідний файл. p>
Якщо
користувач виконує програму в середовищі MS-DOS, він буде повертатися до
MS-DOS. Користувач може завантажити модуль TURBO.EXE і використовувати опції
Search/Find error для локалізації позиції помилки у вихідній програмі
(переконайтеся, що опція Destination встановлена в Disk). Для виявлення помилки
користувач може також використовувати і опцію/F для компілятора командного
рядка (TPC.EXE). p>
(Більше
повне пояснення опцій командного рядка TPC.EXE наведено в розділі 9
"Компілятор командного рядка".) P>
Логіка
помилки. p>
Програма
користувача може містити й логічні помилки. Це означає, що програма
робить те, що їй вказали замість того, що хотілося б. Може бути відсутнім
ініціалізація змінної; можуть виявитися помилковими обчислення; малюнки,
зображені на екрані, виглядають неправильно; програма може просто працювати
не так, як було задумано. Такі помилки перебувають з великим трудом, і
інтегрований відладчик допоможе вам в цьому випадку найкращим чином. p>
Інтегрований відладчик Turbo Pascal. h2>
Деякі
помилки часу виконання (логічні помилки) непомітні і важкі для
простежування. Інші помилки можуть ховатися за невловимим взаємодією
розділів великої програми. У цих випадках необхідно інтерактивне виконання
програми, під час якого здійснюється спостереження за значеннями певних
змінних або виразів. Вам хотілося б, щоб Ваша програма зупинялася
при досягненні певного місця так, щоб побачити, як вона пропрацювала
цей шматок. Вам хотілося б зупинитися і змінити значення деяких
змінних під час виконання програми, змінити визначений режим або
простежити за реакцією програми. І вам хотілося б зробити це в режимі, коли
можливо швидке редагування, перекомпілірованіе і повторне виконання
програми. p>
Інтегрований
відладчик Turbo Pascal має всі описані вище можливості і навіть більше того.
Він представляє собою вбудовану частина інтегрованої вдосконаленою
середовища Turbo Pascal (IDE): для використання пропонуються дві основні функції
меню (Run, Debug), а також деякі клавіші для відладчика команд. Для
додаткової інформації про IDE гарячих клавішах див. розділ 7 "Довідник
по IDE "або довідкову інформацію про Turbo Pascal. p>
Що
може робити відладчик. p>
Інтегрований
відладчик працює дуже просто. Йому не потрібні спеціальні інструкції у Вашому
коді, він не збільшує розмір Вашого. EXE файла і не вимагає перекомпіляції
для створення окремого. EXE файлу після закінчення налагодження. p>
Якщо
Ваша програма поділена на ряд модулів, вихідний код кожного з них
автоматично завантажується в редактор при трасуванні. p>
Якщо
Ви використовуєте оверлеї, відладчик автоматично обробляє їх усередині IDE,
яка виконує перемикання між компілятором, редактором і відладчиком. p>
Огляд
можливостей відладчика: p>
Трасування.
F7 p>
Run/Trace
Into Ви можете виконати один рядок вашої програми, потім перерватися і
подивитися на результати. При виклику процедури або функції усередині вашої
програми, Ви можете задати режим виконання виклику як одного кроку або режим
трасування цієї процедури або функції рядок за рядком. p>
Ви
можете так само трассіровать висновок Вашої програми рядок за рядком. Ви можете
так само встановити, щоб екран переключався за потребою або використовувати
два монітори. Ви можете також встановити екран виводу в окремому вікні. p>
Перехід
на курсор. F4 p>
Run/Go
to Сursor Ви можете пересунути курсор на певну рядок у Вашій
програмі, а потім вказати відладчику виконати програму до досягнення цієї
рядка. Це дає змогу обходити цикли або інші стомлюючі ділянки програми,
це також дозволяє перебиратися в те місце програми, звідки Ви хочете почати
налагодження. p>
Переривання.
p>
З
допомогою команди Debug/Breakpoints Ви можете помітити рядки у Вашій програмі
як точки переривання. Коли в процесі виконання Вашої програми досягається
точка переривання, виконання програми призупиняється і відображається
вихідний текст і курсор зупиняється на рядку з точкою переривання. Потім Ви
можете перевірити значення змінних, почати трасування або виконати
програму до іншої точки переривання. Ви можете підключити умова до точки
переривання. Ви можете також перерватися в будь-якій точці Вашої програми, натиснувши
клавішу Ctrl-Break. Відбудеться зупинка на наступному рядку вихідної
програми, як якщо б у цьому рядку була встановлена точка переривання. p>
Спостереження.
p>
Debug/Watches
Користувач має можливість задавати для перегляду у вікні Watch деякі
об'єкти (змінні, структури даних, вирази). Переглянути дані
змінюються, відображаючи поточні зміни в програмі при покроковому виконанні. p>
Обчислення/модифікація
Ctrl-F4. p>
Debug/Evaluate/Modify
Користувач може викликати вікно Evaluate, що перевірити значення змінних,
структуру даних і вирази в інтерактивному режимі. Використовуючи вікно Evaluate,
Ви можете змінити значення будь-якої змінної, включаючи строки, покажчики,
елементи масиву і поля записів. Це забезпечує простий механізм для
перевірки, як Ваш код реагує на певну установку значень або умов.
p>
Пошук.
p>
Користувач
може швидко знаходити оголошення процедур або функцій, навіть якщо програма
розбита на декілька модулів (Search/Find Рrocedure). Під час трасування Ви
можете швидко повернутися назад з викликів процедур або функцій та перевірити
параметри кожного дзвінка (Window/Call Stack). p>
Підготовка
до використання відладчика. p>
До
початку налагодження Ви повинні розуміти, що основним елементом виконання в
відладчик є рядок, а не оператор. Більш точно найменшим елементом
виконання є рядок. Якщо на одному рядку знаходиться декілька
операторів, вони будуть виконуватися разом при натисненні F7. З іншого боку, якщо
один оператор розміщений на декількох рядках, то при натисненні F7 буде виконуватися
весь оператор. Всі команди виконання грунтуються на рядках, включаючи
покрокову налагодження та точки переривання; рядок, на якій знаходиться виконання,
завжди відзначена курсором виконання. p>
Перш,
ніж почати налагодження програми, Ви повинні задати для компілятора Turbo Pascal
інструкцію з генерації таблиці символів і таблиці номерів рядків цієї
програми. Таблиця символів є невеликою базу даних з
використовуваними ідентифікаторами - константами, типами, змінними, процедурами
та інформацією про номери рядків. Директиви компілятора $ D + і $ L + роблять це по
умовчанням; вони відповідають елементам меню Options/Compiler/Debug Information
і Options/Compiler/Local Symbols. Так само за умовчанням встановлена опція
Options/Debugger/Integrated, яка генерує налагоджувальну інформацію в
для виконання на файлі. p>
Директива
($ D +) генерує таблицю номерів рядків, яка встановлює відповідність
між об'єктним кодом і вихідним модулем. Директива ($ L +) генерує локальну
налагоджувальну інформацію, а саме, будує список ідентифікаторів, локальних для
кожної процедури або функції, для того, щоб відладчик міг зберігати інформацію про
них у процесі налагодження. Коли Ви використовуєте директиви компілятора, розділяйте
комами та без пробілів, і ставлячи $ тільки перед першим директивою; наприклад
($ D +, L +). p>
Примітка:
Ви можете відключити ці перемикачі для збереження пам'яті або дискового
простору під час компіляції. p>
Коли
Ви виконуєте покрокову налагодження, Turbo Pascal буде іноді переключатися на
екран користувача, виконувати Ваш код, а потім повертатися в інтегровану
середу, очікуючи наступної команди. Ви можете керувати перемиканням екрана з
допомогою установок Options/Debugger/Display Swapping, які можуть приймати 3
значення: p>
Smart:
Це режим за замовчуванням. Середа IDE перемикається на екран користувача, коли
програма звертається до відеопам'яті або при виклику програми. p>
Always:
Переключення на екран користувача відбувається на кожному кроці. p>
None:
Переключення екранів не відбувається. Інтегроване середовище залишається видимою все
час. Якщо в програмі передбачається виведення на екран чи потрібне введення
інформації, текст буде писатися на екрані середовища. Ви можете відновити вікна
інтегрованого середовища, вибираючи Е/Refresh Display. p>
Початок
сеансу налагодження. p>
Найбільш
швидкий спосіб почати налагодження полягає у завантаженні програми і виборі команди
Run/Trace Into (F7). Програма буде компілюватися. Коли компіляція
завершиться, редактор відобразить на дисплей тіло основної програми з індикацією
строки виконання на першому операторі begin. Користувач може почати
трасування програми з цього місця (натиснути клавіші F7 чи F8) або використовувати
інші методи які наведені нижче. p>
Якщо
користувачеві необхідно почати налагодження з певного місця програми, він
може виконати програму до цього місця, а потім зупинитися. Для цього,
завантажте потрібний розділ вихідного модуля в редактор і пересуньте курсор на
рядок, де ви бажаєте зупинитися. Потім можна зробити двома способами: p>
--
Вибрати команду Run/Goto Cursor (або натиснути клавішу F4), яка буде
виконувати програму користувача до досягнення рядки з позначкою курсором, а
потім останавіть роботу програми. p>
--
Поставити на зазначеній рядку точку переривання (вибрати команду Debug/Toggle
Breakpoint або натиснути на Ctrl-F8), потім виконати програму (виконати команду
Run/Run або натиснути Ctrl-F9); зупинка буде відбуватися кожного разу при
досягненні заданої рядки. Ви можете задати кілька точок переривання, в цьому
випадку програма буде робити зупинку кожного разу при досягненні якої-небудь з
цих точок. p>
рестарт
сеансу налагодження. p>
Якщо
в процесі налагодження програми виникає необхідність почати все спочатку, то
потрібно виконати команду Program Reset з меню Run. Система налагодження повторно
ініціалізується, і команда наступного кроку поверне вас до першого рядку головної
програми. При цьому проводиться закриття всіх файлів, які були відкриті
програмою, очищення стека всіх вкладених програм, які викликалися
програмою, і звільнення всього використаного простору купи. Змінні програми,
проте, не будуть повторно ініціалізований або зазнають модифікації
якого-небудь іншого виду. (Turbo Pascal ніколи не ініціалізує змінні
автоматично). Однак, початкові значення тіпірованних констант програми
будуть відновлені. p>
Turbo
Pascal також пропонує рестарт, якщо Ви робите будь-які зміни в
програмі під час налагодження. Наприклад, якщо ви змінюєте частина програми, а
потім вибираєте будь-яку команду виконання (натискаєте клавіші F7, F8, F4, Ctrl-F9
і т.д.), Ви отримаєте повідомлення: Source modified, rebuild? (Y/N) (вихідний
модуль модифікований, потрібно повторити збірку? так/ні). Якщо Ви відповідаєте Y,
Turbo Pascal буде перекомпіліровать програму і відновить налагодження програми з
початку. Якщо Ви відповісте N, Turbo Pascal припускає, що Ви впевнені у своїх
діях, і продовжує сеанс налагодження далі. (Будь-які зміни в програмі,
які Ви зробили, не будуть впливати на її виконання до тих пір, поки Ви не
перекомпіліруете програму). Якщо ви додали або видалили рядки програми,
курсор виконання не реагує на ці зміни, і може виявитися, що буде
виділятися помилкова рядок. p>
Закінчення
сеансу налагодження. p>
В
процесі налагодження програми Turbo Pascal зберігає трасу того, що Ви робите, та
де ви в даний момент. Так як користувач може в процесі налагодження
завантажувати і навіть редагувати різні файли, Turbo Pascal не інтерпретує
завантаження іншого файла в редактор, як кінець сеансу налагодження. Тому, якщо ви
бажаєте виконати або налагодити іншу програму, потрібно виконати команду
Run/Program Reset (клавіша Ctrl-F2). p>
Трасування Вашої програми. h2>
Найпростіша
техніка налагодження - це крок за кроком налагодження, яка трасує усередині процедур і
функцій. Завантажте програму RANGE.PAS в Turbo Pascal. p>
($ D +, L +)
p>
(Для
того, щоб забезпечити p>
повну
генерацію налагоджувальної інформації) p>
($ R-)
(Для того, щоб відключити перевірку діапазону) p>
program RangeTest; p>
var p>
List: array [1 .. 10] of integer; p>
Indx: integer; p>
begin p>
for Indx: = 1 to 10 do
List [Indx]: = Indx; p>
Indx: = 0; p>
while (Indx <11) do p>
begin p>
Indx: = Indx 1; p>
if List [Indx]> 0 then p>
List [Indx]: =- List [Indx] p>
end; p>
for Indx: = 1 to 10 do
writeln (List [Indx]); p>
end.
p>
Почніть
налагодження, натиснувши клавішу F7. Це покрокова команда. Turbo Pascal справить
компіляцію автоматично, а потім підготуватися до покрокової обробці цієї
програми. Зауважимо, що курсор виконання розташований на операторі begin (рядок
7). Пам'ятайте, що курсор виконання позначає наступний рядок програми, яка
повинна бути виконана. p>
Натисніть
клавішу F7 кілька разів. Курсор виконання переміститься на оператор
List [Indx]: = Indx і зупиниться. Це означає, що рядок виконується у циклі. p>
Виберіть
команду Debug/Watches/Add Watch (Ctrl-F7) дЩоб переглянути у вікні Add Watch. Ви
можете переглядати значення змінних, структур даних або виразів у вікні
Watch. p>
Те,
що з'явиться у вікні Add Watch залежить від того, де розташовується курсор, коли
Ви натискаєте на клавішу Ctrl-F7. Якщо Курсор знаходиться на першій букві будь-який
алфавітно-цифровий рядки, усередині рядка або відразу за нею, рядок буде
буде скопіювати у вікно Add Watch і підсвічуватиметься. Так, якщо курсор був
спозиціонували на слові Indx, то Indx з'явиться у вікні. Якщо у вікні необхідно
що-небудь змінити, почніть набір на клавіатурі і первісне вираження і
підсвічування зникнуть. p>
Як
тільки з'явиться вікно Add Watch, незалежно від його вмісту, можна додати до
нього текст, якщо натиснути клавішу Ў (яка копіює додатковий текст з
редактора). Помістіть List у вікно, використовуючи Ў, і натисніть Enter. Тоді у вікні
Watch в нижній частині екрана з'явиться рядок: p>
List
: (1,2,0,0,0,0,0,0,0,0) p>
Cнова
натисніть клавішу Ctrl-F7, наберіть слово Indx та натисніть Enter. Indx буде першим
в списку у вікні Watch: p>
Indx
: 3 p>
List
: (1,2,0,0,0,0,0,0,0,0) p>
Натисніть
клавішу F7 знову і Ви побачите, що значення Indx і List у вікні Watch зміняться,
відображаючи роботу Вашої програми. p>
Як
тільки Ви увійдете до циклу while, Ви знову побачите, що значення Indx і List
змінюються крок за кроком. Зауважимо, що ці зміни у вікні Window відображають
дії кожного рядка циклу після натискання клавіші F7. p>
Продовжуйте
натискати на клавішу F7, поки не досягнете початку циклу while, c Indx рівним
10. Під час проходження через цикл, Ви можете спостерігати як змінюються
значення у вікні Watch. Коли виконується оператор p>
List
[Indx]: = - List [Indx]; p>
значення
Indx зміниться на -11. Якщо Ви продовжуєте натискати на F7, то виявиться, що
ви увійшли в нескінченний цикл. p>
Таким
чином, якщо Ви наберете таку програму, вона буде компілюватися і
виконуватися. Виходить нескінченний цикл, так як цикл while виконується 11
раз, а не 10, і останнє значення змінної Indx одно 11. Так як масив
List містить тільки 10 елементів, значення List (11) буде вказувати на
деяку позицію пам'яті поза масиву List. Через способу розподілу змінних
вже виявиться, що значення List (11) займе в пам'яті теж місце, що і
мінлива Indx. Це означає, що при Indx = 11, запис: p>
List
[Indx]: = - List [Indx] p>
ідентична
запису p>
Indx
: =-Indx. p>
Так
як значення змінної Indx одно 11, цей оператор змінить її значення на
-11. У результаті в програмі розпочнеться повторне виконання циклу. Цей цикл
тепер змінює додаткові байти в місці, що відповідає List [-11 .. 0]. І
тому що значення Indx ніколи не буде закінчувати цикл із значенням більшим чи
рівним 11, то цикл ніколи не закінчиться. p>
Важливо
наголосити на тому, що використовуючи лише дві клавіші (F7 і Ctrl - F7), через кілька
хвилин, Ви швидко і легко простежується проміжні значення змінних і
знаходите помилку. p>
Покрокове
виконання програми. p>
Різниця
між командами Trace Into (F7) і Step Over (F8) в тому, що при використанні
F7 здійснюється трасування усередині процедур і функцій, в той час як
використання F8 призведе до обходу викликів підпрограм. Ці команди мають
особливе значення при виконанні оператора begin основної програми, якщо
програма використовує модулі, які мають розділ ініціалізації. У цьому випадку,
використання F7 призведе до трасуванні розділу ініціалізації кожного модуля,
що дозволяє побачити, що ініціалізується в кожному модулі. При використанні
F8 ці розділи не будуть трассіроваться, і курсор виконання переходить на
наступний рядок після begin. p>
Розглянемо
наступний (неповний) приклад програми: p>
($ D +, L +) p>
program TestSort; p>
const p>
NLMax = 100; p>
type p>
NumList = array [1 .. NLMax] of integer; p>
var p>
List: NumList; p>
I, Const: word; p>
procedure Sort (var L: NumList;
Cnt: Integer); p>
begin p>
(sort the list) (сортування списку) p>
end; (of proc sort) (процедури Sort) p>
begin p>
randomize; p>
Count: = NLMax; p>
for I: = 1 to Count do p>
List [I]: = Random (1000); p>
sort (List, Count); p>
for I: = 1 to Count do p>
Write (List [I]: 8); p>
Readln
p>
end.
(програми TestSort) p>
Припустимо,
що Ви налагоджувати процедуру Sort. Ви хочете здійснити трасування процедури
Sort, включаючи перевірку значення всередині List до виклику Sort. Однак, виконувати
100 раз ініціалізацію всередині List дуже втомлює. Чи є спосіб виконувати
цикл, не зупиняючись на кожній виконуваної рядку. p>
Так,
фактично, існує кілька способів. По-перше, Ви могли б виділити цей
цикл в окрему процедуру і натиснути клавішу F8 для того, щоб обійти її
трасування, але це дуже нераціонально. По-друге, Ви могли б встановити
усередині програми точку переривання. Ми пояснимо, що це за точки переривання, і
як вони використовуються трохи пізніше. Зрештою, Ви могли б використати
команду Run/Go to Cursor (F4). Перемістіть курсор на рядок з викликом Sort, а
потім натисніть на клавішу (F4). Ваша програма буде виконуватись до досягнення
рядки з позначкою курсором. Курсор виконання переміститься на цей рядок; потім
Ви можете почати трасування з цього місця, натискаючи на клавішу F7, для того,
щоб можна було зробити трасування всередині Sort. p>
Команда
Run/Goto Cursor (F4) діє на вкладених рівнях викликів підпрограм, навіть
якщо їх вихідний код знаходиться в іншому файлі. Наприклад, Ви могли б мати
курсор де-небудь усередині процедури Sort і натиснути на клавішу F4; програма
виконувалася б до цього рядка. По суті, Sort могла б бути виділена в
окремий модуль, відладчик б уже знав, коли потрібно зупинитися і що
відобразити. p>
Існують
три випадки, коли команда Go to Cursor (F4) не буде виконувати програму до
зазначеної курсором рядка. p>
Перший,
коли Ви розташували курсор між двома виконуваними рядками; наприклад, на
порожній рядку або рядку з коментарями. У цьому випадку програма буде
виконуватися до наступного рядка, що містить оператор, який може бути
виконаний. p>
Другий
випадок, коли курсор розташований поза процедурного блоку, наприклад, на операторі
оголошення змінної або оператора program. Усунення несправностей буде виводити повідомлення
"no code generated for this line" (для цього рядка код не
генерується). p>
Третій
випадок, коли Ви маєте в своєму розпорядженні курсор на рядок, яка ніколи не виконується.
Наприклад, рядок розташовується вище курсору виконання (передбачається, що ви
знаходитесь не в циклі) або рядок є частиною else - умовного оператора,
коли вираз if має значення true. У цьому випадку відладчик буде
діяти так, як якщо б виконувалася команда Run/Run (Ctrl-F9); програма
буде виконуватися до кінця або до точки переривання. p>
Припустимо,
що Ви трассіруете процедуру Sort, потім хочете завершити роботу програми і
посмотреть вихідні результати. Яким способом це зробити? Спочатку потрібно
перемістити курсор до останнього оператору end основної частини програми, а потім
виконати команду Run/Go to Cursor (F4). Або простіше, потрібно виконати команду
Run/Run (Ctrl-F9). Вона дозволяє відладчику продовжити нормальне виконання
програми користувача. Програма буде виконуватися до кінця, або до тих пір,
поки Ви не досягнете точки переривання або не буде натиснуто Ctrl-Break. p>
Використання
точок переривання. p>
Точки
переривання є важливим інструментом налагодження. Точка переривання подібна знаку
зупинки, введеного в програму користувача. Коли програма зустрічає таку
точку, вона зупиняє своє виконання і чекає подальших налагоджувальних
інструкцій. p>
Примітка:
Ви можете мати до 16 активних точок переривання. p>
Зауважимо,
що точки переривання існують тільки під час сеансу налагодження; вони не
зберігаються у файлі. EXE, якщо програма компілюється на диск. Щоб визначити
точку переривання, використовуйте звичайні команди редагування для переміщення
курсор у рядок програми, де Ви хочете зробити паузу. Кожного разу
виконуйте команду Debug/Toggle Breakpoint (Ctrl-F8). Коли рядок відзначається
як точка переривання, вона висвічується. Це не має бути порожній рядок,
коментарі, директиви компіляції; оголошення констант, типів, міток,
змінних; заголовком програми, модуля, процедури або функції. Як тільки Ви
задали точки переривання, виконуйте програму за допомогою команди Run/Run
(клавіша Ctrl-F9). Спочатку програма буде виконуватися нормально. Коли
зустрінеться точка переривання, програма зупиниться. Відповідний вихідний
файл (основна програма, модуль або включений файл) завантажується у вікно Edit,
яке візуалізується на екрані і курсор виконання вміщується на рядок з
точкою переривання. p>
Зауважимо,
що точка переривання НЕ висвічується, коли на ній знаходиться курсор
виконання. Якщо будь-які змінні, або вирази були додані у вікно
Watch, то вони також виводяться на дисплей зі своїми поточними значеннями. p>
Потім,
користувач може використовувати будь-який режим налагодження. p>
Ви
можете здійснювати послідовне виконання програми, використовуючи команду Run /
Trace Into, Step Over або Go to Cursor (F7, F8 або F4). Ви можете перевірити або
змінити значення змінних. p>
Ви
можете додати або видалити вирази з вікна Watch. p>
Можна
призначити або видалити точки переривання. p>
Можна
переглянути вихідні результати програми, використовуючи команду Windows/User
Screen (Alt-F5). p>
Ви
можете запустити програму з початку (Run/Program Reset і, потім, команду
покрокового виконання). p>
Можна
продовжити виконання до наступної точки переривання (або до кінця програми),
виконавши команду Run/Run (Ctrl-F9). p>
Для
видалення точки переривання з рядка перемістіть курсор на дану рядок і,
виконавши команду Debug/Toggle Breakpoint (або натисніть Ctrl-F8) ще раз. Ця
команда включає або відключає точку переривання в рядку, якщо вона використовується
для рядка з точкою переривання, то рядок стає нормальною. p>
Давайте
повернемось до нашого прикладу, який було розглянуто раніше. p>
begin
(основна частина програми Test.Sort) p>
Randomize; p>
Count: = NLMax; p>
for I: = 1 to Count do p>
List [I]: = Random (1000); p>
Sort (List, Count); p>
for I: = 1 to Count do p>
Write (List [I]: 8); p>
Readln p>
end. (програма Test.Sort) p>
Як
вже говорилося, ідея була в тому, щоб обійти початковий цикл і почати
трасування з виклику процедури Sort. Новий варіант. Наведіть курсор на рядок
з викликом процедури і виконайте команду Debug/Toggle Breakpoint (Ctrl-F8),
яка відзначить рядок, як точку переривання. Тепер виконайте програму до
цієї точки, використовуючи команду Run/Run (Ctrl-F9). Коли програма досягне
цього рядка, вона зупиниться і дозволить Вам почати налагодження. p>
Використання
Ctrl-Break. p>
Крім
призначення точок переривання, користувач може зробити негайну зупинку
під час виконання програми, використовуючи клавішу Ctrl-Break. Це означає, що
можна перервати роботу програми в будь-який час. Коли Ви натискаєте на клавішу
Ctrl-Break, виконання програми припиняється. Ви повертаєтеся в редактор,
курсор виконання розташований на наступному рядку програми, і програма готова
до подальшого послідовне виконання. p>
Фактично,
відладчик автоматично підключає DOS, BIOS і інші сервісні функції. Він
знає, чи є поточний виконується код програмою DOS, програмою BIOS
або програмою користувача. Коли Ви натискаєте на клавішу Ctrl-Break, відладчик
чекає, поки програма виконується сама. Потім він робить послідовне виконання
інструкцій машинного рівня, поки така інструкція не буде на початку рядка
вихідного коду на Паскалі. З цього моменту відладчик припиняє роботу,
переміщує курсор виконання на цей рядок і пропонує Вам натиснути на клавішу
ESC. p>
Примітка:
Якщо користувач натискає на клавішу Ctrl-Break другий раз ще до того, як
відладчик знаходить і відображає наступний рядок вихідного коду для виконання,
то відладчик завершує роботу і не намагається знайти рядок вихідного коду. У цьому
випадку, процедури виходу не виконуються, що означає, що файли, відеорежим і
розподіл пам'яті DOS можуть бути не повністю очищені. p>
Перегляд
значень. p>
Виконання
програми надає багато інформації, але не в тому обсязі, як хотілося б.
Може виникнути необхідність переглянути за тим, як змінюються значення
змінних під час виконання програми. Розглянемо процедуру Sort з
попередньої програми: p>
procedure
Sort (var L: NumList; C: word); p>
var p>
Top, Min, k: word; p>
Temp: integer; p>
begin p>
for Top: = 1 to C-1 do p>
begin p>
Min: = Top; p>
for k: = Top 1 to C do p>
if L [k] Top then p>
begin p>
Temp: = L [Top]; p>
Top: = L [Min]; p>
L [Min]: = Temp; p>
end; p>
end; p>
end;
(процедури Sort) p>
Примітка:
Змініть NLMax в тілі програми на 10 так, щоб Ви могли працювати з меншим
масивом. p>
В
цієї процедури є помилки, будемо переглядати її (використовуючи команду Run/Trace
Into або клавішу F7) і спостерігати за значеннями змінних L, Top, Min і k. p>
Усунення несправностей
дає можливість користувачеві задати об'єкти для перегляду під час виконання
Вашої програми. Як Ви й припускаєте, об'єктами перегляду є
змінні, структури даних і вирази, розташовані у вікні Watch, де
відображаються їх поточні значення, поновлюються у міру виконання кожного рядка
програми. Давайте повернемося до попереднього прикладу. Встановити об'єкти
спостереження просто. p>
наведіть
курсор до кожного ідентифікатором і виконуйте команду Debug/Watch/Add Watch
(Ctrl-F7) для долучення кожного виразу у вікно Watch. p>
Результат
може виглядати так: p>
k
: 21341 p>
Min
: 51 p>
Top
: 21383 p>
L
: (163,143,454,622,476,161,850,402,375,34) p>
Передбачається,
що Ви тільки-но увійшли в процедуру Sort, курсор виконання розташований на
початковому операторі begin. (Якщо Ви ще не ввійшли в процедуру Sort, то для
кожного виразу у вікні Watch буде з'являтися повідомлення "unknown
identifier "(невідомий ідентифікатор), поки ви не ввійдете в процедуру).
Зауважимо, що змінні K, Min і Top мають довільні значення, тому що вони ще
не були ініціалізований. Значення змінної L, імовірно, теж повинно
бути довільним; вони не будуть такими при виконанні всієї програми, усі вони
повинні бути невід'ємними і лежати в інтервалі від 0 до 999. p>
Якщо
натиснути на клавішу F7 чотири рази, то ми просунемося до рядка if L [k] Top then,
тому до вершини зовнішнього циклу, і знову вниз до рядка if L [k]
k
: 3 p>
Min
: 2 p>
Top
: 2 p>
L
: (34,143,454,622,476,161,850,402,375,34) p>
Тепер
Ви можете помітити дві речі. Перше, останнє значення змінної L (34),
що є також і найменшим значенням, скопіювати в першу значення
L, і значення, яке вже було там раніше (163), зникло. Друге, змінні
Min і Top мали однакові значення під час трасування процедури. Фактично,
Ви можете помітити, що змінна Min отримує значення змінної Top, але вона
ніколи не змінюється де-небудь ще. Проте, нижче циклу розташовується перевірка: p>
if
MinTop then. p>
Або
ця перевірка є хибною, чи існує якась невідповідність між цими двома
частинами процедури. Виявляється, є хибною п'ятий рядок програми. Вона повинна
виглядати так: p>
Min
: = K, замість L [Min]: = L [k]. p>
Виправте
рядок, перемістіть курсор до початкового оператору begin у процедурі Sort і
виконайте команду Run/Go to Cursor (F4). Так як Ви змінили програму, на
екрані з'явиться вікно з питанням Source modified, rebild? (Y/N) (вихідний модуль
модифікований, чи потрібна збірка? Так/Ні). Ответьте Y. Програма буде
перекомпіліровать, розпочнеться її виконання, потім відбудеться зупинка на
початковому операторі begin процедури Sort. Тепер програма працює правильно.
Значення першого елемента тепер не змінюється на найменше з значень
елементів масиву L, відбувається обмін-переміщення значення першого елемента
масиву на місце, де до цього розташовувався елемент з найменшим значенням.
Потім процес повторюється з другою позицією, третій і т.д., поки список
елементів не буде відсортований повністю. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://bestcode.org/
p>