Що таке налагоджувач і як він може допомогти мені діагностувати проблеми?


101

Це має бути загальним запитанням для допомоги новим програмістам, які мають проблеми з програмою, але не знають, як за допомогою налагоджувача діагностувати причину проблеми.

Це питання охоплює три класи більш конкретного питання:

  • Коли я запускаю свою програму, вона не видає результату, який я очікую для вводу, який я їй дав.
  • Коли я запускаю програму, вона аварійно завершує роботу і дає мені стек стека. Я вивчив трасування стека , але досі не знаю причину проблеми, оскільки трасування стека не надає мені достатньо інформації.
  • Коли я запускаю програму, вона аварійно завершує роботу через помилку сегментації (SEGV).

3
Хороша робота - також було б добре мати відповідні запитання та відповіді щодо методів налагодження , наприклад, за допомогою налагоджувача, інших інструментів налагодження (наприклад, valgrind), стратегічних printfs, стрес-тестування, поділяй і володар і т. Д.
Пол R

1
Я погоджуюсь з @PaulR, FAQ повинен містити подібні речі.
Ніку Стіурка

Відповіді:


65

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

Використання налагоджувача - очікувана базова навичка

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

Як налагоджувач може вам допомогти

За допомогою налагоджувача ви можете виявити, чи має змінна неправильне значення, і де у вашій програмі її значення змінилося на неправильне значення.

За допомогою одного кроку ви також можете виявити, чи є потік управління таким, як ви очікуєте. Наприклад, чи має бути ifвиконана гілка, коли ви очікуєте, що це має бути.

Загальні примітки щодо використання налагоджувача

Особливості використання налагоджувача залежать від налагоджувача і, меншою мірою, від мови програмування, яку ви використовуєте.

  • Ви можете приєднати налагоджувач до процесу, на якому вже запущена ваша програма. Ви можете зробити, якщо ваша програма застрягла.

  • На практиці часто легше запускати програму під контролем налагоджувача з самого початку.

  • Ви вказуєте, де ваша програма повинна зупинити виконання, вказуючи файл вихідного коду та номер рядка, на якому слід зупинити виконання, або вказуючи назву методу / функції, на якій програма повинна зупинитися (якщо ви хочете зупинити як як тільки виконання входить у метод). Технічний засіб, який використовує налагоджувач для зупинки вашої програми, називається точкою зупинки, а цей процес - встановленням точки зупинку .

  • Більшість сучасних налагоджувачів є частиною IDE і надають вам зручний графічний інтерфейс для вивчення вихідного коду та змінних вашої програми, а також інтерфейс вказує та клацає для встановлення точок зупинки, запуску програми та покрокового її запуску.

  • Використання налагоджувача може бути дуже складним, якщо файли виконуваної програми або файли байт-коду не включають інформацію про налагодження символів та перехресні посилання на ваш вихідний код. Можливо, вам доведеться скомпілювати (або перекомпілювати) програму дещо інакше, щоб забезпечити наявність інформації. Якщо компілятор виконує велику оптимізацію, ці перехресні посилання можуть стати заплутаними. Тому, можливо, доведеться перекомпілювати програму з вимкненими оптимізаціями .


4
Це неповно, оскільки він пропускає найважливіший з усіх налагоджувачів, який потенційно може значно зменшити кількість питань щодо Stackoverflow (я передбачаю щонайменше на 20%) - відладчики javascript: firebug, Chrome, Firefox, IE9 + інтегрований налагоджувач , IE8- Visual Studio тощо
slebetman

1
Також для node.js - інспектор вузлів. Але програмісти node.js не задають стільки основних питань та / або виправлення мого коду, скільки загальні програмісти javascript.
slebetman

38

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

  • Частина вашої програми, яка зазнає невдачі, насправді велика (погана модуляризація, можливо?), І ви точно не впевнені, з чого почати переходити через код. Перехід через все це може зайняти багато часу.
  • Ваша програма використовує багато зворотних викликів та інших нелінійних методів управління потоком, що змушує відладчик заплутатися, коли ви проходите через нього.
  • Ваша програма багатопотокова. Або ще гірше, ваша проблема викликана перегоном.
  • Код, в якому є помилка, запускається багато разів, перш ніж виправити помилку. Це може бути особливо проблематично в основних циклах або, що ще гірше, у фізичних двигунах, де проблема може бути числовою. Навіть встановлення точки зупинку, у цьому випадку, просто призвело б до того, що ви натискали її багато разів, а помилка не з’являлася.
  • Ваша програма повинна працювати в режимі реального часу. Це велика проблема для програм, які підключаються до мережі. Якщо ви встановите точку зупинки у своєму мережевому коді, інший кінець не буде чекати, поки ви пройдете, це просто тайм-аут. Програми, які покладаються на системний годинник, наприклад, ігри з фреймкіпом, теж не набагато краще.
  • Ваша програма виконує деструктивні дії, такі як запис у файли або надсилання електронних листів, і ви хочете обмежити кількість разів, необхідних для її проходження.
  • Ви можете сказати, що ваша помилка спричинена неправильними значеннями, що надходять до функції X, але ви не знаєте, звідки ці значення. Потрібно знову і знову запускати програму, встановлюючи точки зупинку все далі і далі, може бути величезною проблемою. Особливо, якщо функція X викликається з багатьох місць у програмі.

У всіх цих випадках або різка зупинка програми може спричинити різницю в кінцевих результатах, або проходження вручну у пошуках одного рядка, в якому виникла помилка, - це занадто великі клопоти. Подібне може траплятися як у випадку вашої помилки, або у збої. Наприклад, якщо пошкодження пам'яті спричиняє збій, до того моменту, коли збій стався, це вже занадто далеко від місця, де спочатку сталося пошкодження пам'яті, і корисної інформації не залишилось.

Отже, які альтернативи?

Найпростішим є просто реєстрація та твердження. Додайте журнали до програми в різні моменти та порівняйте отримане з тим, що очікуєте. Наприклад, подивіться, чи взагалі навіть викликана функція, де, на вашу думку, є помилка. Подивіться, чи є змінні на початку методу такими, якими ви їх вважаєте. На відміну від точок зупинку, це нормально, коли існує багато рядків журналу, в яких нічого особливого не відбувається. Після цього ви можете просто шукати журнал. Після того, як ви потрапите в рядок журналу, який відрізняється від того, що ви очікуєте, додайте більше в ту ж область. Звужуйте його все далі і далі, поки він не стане достатньо малим, щоб можна було реєструвати кожен рядок у виправленій області.

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

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

У випадку витоків пам’яті або тупіння пам’яті використовуйте відповідні інструменти, які можуть аналізувати та виявляти їх під час виконання. Першим кроком є ​​можливість виявити, де відбувається справжня корупція. Після цього ви можете використовувати журнали, щоб повернутися до місця, де були введені неправильні значення.

Пам'ятайте, що налагодження - це процес, що повертається назад. У вас є кінцевий результат - помилка - і ви знайдете причину, яка їй передувала. Мова йде про те, щоб рухатися назад, і, на жаль, налагоджувачі лише крокують вперед. Тут хороший журнал та аналіз післясмертних випадків можуть дати набагато кращі результати.


10
Це була б гарна відповідь ... на інше питання. Це погана відповідь на це питання. Можливо, вам слід поставити це запитання та опублікувати це як відповідь на нього.
Raedwald,

7
Фактичне запитання описується як "допомога новим програмістам, які мають проблеми з програмою", "вона не видає очікуваних результатів" та "Я вивчив трасування стека, але я все ще не знаю причину проблеми" . Всім цим допомагає ця відповідь. Крім того, пояснюючи, що робить налагоджувач, не менш важливо пояснити, чим він не займається .
SlugFiller

5
Чудова відповідь. Я завжди використовував налагоджувач як основний інструмент для пошуку помилок. Але зараз я працюю в проекті, де величезний компонент інфраструктури використовує багато потоків і багато мережевого коду (клієнт / сервер) і помічаю, що налагоджувач - це останнє, що мені допомагає. Ви згадали багато речей, де вам дійсно слід використовувати інший інструмент, а не покладатися на свій старий добрий налагоджувач (найголовніше: реєстрація).
Тім Шмельтер

"Ви можете сказати, що ваша помилка викликана неправильними значеннями, що надходять до функції X, але ви не знаєте, звідки ці значення беруться" Це особливо важко налагоджувати. Як ви зазвичай займаєтесь виправленням чогось подібного?
Айшан Хакверділі

2
@Ayxan Певною мірою, якщо вам вдалося змусити функцію розірватися на затвердженні, ви можете використовувати стек викликів, щоб отримати абонента. Але одне лише це не дає вам джерела значення, оскільки значення, швидше за все, походить із попереднього рядка. Ви в основному повинні стежити за значенням назад, через різні змінні, через які воно проходить. Якщо ви добре уявляєте шлях, яким рухаються дані, ви можете просто створити купу відбитків журналу та спробувати звузити місце, де воно "йде не так". Якщо ні, то вам знадобиться окремий запуск програми (відтворення помилки) для кожного кроку назад.
SlugFiller
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.