Який процес ви зазвичай використовуєте під час спроби налагодження проблеми / проблеми / помилки у вашому програмному забезпеченні? [зачинено]


15

Здається, більшість людей налагоджують проблему як мистецтво, а не як науку. Для тих, хто тут трактує це як науку, а не як мистецтво - який процес ви зазвичай використовуєте, стикаючись з новою проблемою / помилкою / проблемою?

Відповіді:


13

Загалом кажучи, те, що я роблю, це:

  1. Спробуйте вирішити проблему. Подумайте, що змінилося, коли помилка вперше з’явилася. Що там, де ти працюєш? Яку частину коду ви змінювали? 99% мої помилок вирішуються таким чином. Зазвичай це щось дурне.

  2. Якщо у мене є здогадки про те, де проблема, уважно подивіться на код, який, здається, є причиною. Читати. Прочитайте навіть вголос. Запитайте себе: "Чого я намагаюся досягти?". Для деяких типів проблем: Чи може це мати якісь побічні ефекти чи вплинути на нього кодом в іншому місці так, як я не думав?

  3. Спробуйте різними способами проаналізувати, що піде не так, де і коли (див. Нижче).

  4. Якщо я все ще не маю підказки, я перевіряю, чи є в старшій версії мого джерела таку ж проблему, спробуйте знайти, коли в моїй хронології розвитку проблема з'явилася вперше. Для цього вам потрібно працювати з хорошою системою контролю версій, наприклад, git (git має функцію під назвою bisect саме для цього виду налагодження).

  5. Якщо досі немає підказки, перервіться .... це насправді часто допомагає.

  6. Поверніться до креслярської дошки - перегляньте, як має працювати ваша програма і чи це насправді має сенс.

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

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

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


1
+1 за перерву. Найскладніші проблеми ускладнюються лише тоді, коли ви зриваєтесь і на 6-й годині налагоджуєте їх. Знання, коли зробити перерву - одна з найкорисніших навичок налагодження, яку я отримав.
Бред Гарднер

Дивовижна відповідь. Я не можу краще зробити
EricBoersma

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

1
Відмінна відповідь. Я просто хочу додати, що унція профілактики коштує фунта ліки. Велика частина мого процесу налагодження полягає в тому, що я кодую, в першу чергу, я вношу лише невеликі, поступові зміни та компілюю, тестую та здійснюю локально між ними. Таким чином, якщо раптом з’явиться помилка, ймовірний список підозрюваних дуже малий і легко його побачити за допомогою bzr qdiffкоманди.
Карл Білефельдт

8

Я намагаюся використовувати тестово-керовану розробку ( TDD ). Я пишу тест, який повторює помилку, потім намагаюся пройти тест. Іноді акт написання тесту допомагає знайти помилку.

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

Деякі посилання:


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

1
Він отримує стільки оновлень, тому що включає магічну абревіатуру: TDD.
Bjarke Freund-Hansen

@Alex - я додав декілька посилань. Приклад "Знайди помилку, напиши тест" має приклад. Я можу розширити це, але це дійсно так просто.
TrueWill

7

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

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

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

  • Вузьке спостереження : вивчайте інформацію, що безпосередньо оточує конкретну проблему, якщо вона застосовується. Очевидними тут є стек викликів, локальні змінні, якщо ви їх бачите, рядки коду, що оточує проблему. Цей тип специфічного дослідження місця розташування не завжди застосовується. Наприклад, вивчення "повільної" системи може не мати очевидного початкового місця, як це, але ситуація з аварією або внутрішніми помилками, ймовірно, матиме негайний і очевидний момент інтересу. Одним із конкретних кроків тут може бути використання таких інструментів, як windbg (запускати! Аналізувати -v на завантаженому дамп аварійного завершення, і дивитись на те, що він вам каже).

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

  • Гіпотеза: Це справді весела частина (і мені не дуже пильно, коли це весело). Це часто вимагає великої логічної думки у зворотному напрямку. Дуже приємно думати про те, як система перейшла в поточний стан. Я підозрюю, що це частина, яку багато хто вважає мистецтвом. І я вважаю, що це може бути, якщо програміст просто починає випадково кидати речі, щоб побачити, що палить. Але з досвідом це може бути досить чітко визначеним процесом. Якщо ви думаєте дуже логічно в цей момент, часто можна визначити можливі набори шляхів, які призвели до даного стану. Я знаю, що ми перебуваємо в стані S5. Щоб це сталося, S4a або S4b мали відбутися, а може бути, S3 перед S4a і т. Д. Частіше цього немає, може бути кілька елементів, які можуть призвести до заданого стану. Іноді це може допомогти записати на подряпину простий простий потік або діаграму стану або ряд кроків, пов'язаних із часом. Реальні процеси тут сильно відрізнятимуться в залежності від ситуації, але серйозна думка (і повторне вивчення на попередніх етапах) в цей час часто дають одну чи кілька правдоподібних відповідей. Також зауважте, що надзвичайно важливою частиною цього кроку є усунення неможливих речей. Видалення неможливого може допомогти обрізати простір рішення (згадайте, що Шерлок Холмс сказав про те, що залишилося після усунення неможливого). Також зауважте, що надзвичайно важливою частиною цього кроку є усунення неможливих речей. Видалення неможливого може допомогти обрізати простір рішення (згадайте, що Шерлок Холмс сказав про те, що залишилося після усунення неможливого). Також зауважте, що надзвичайно важливою частиною цього кроку є усунення неможливих речей. Видалення неможливого може допомогти обрізати простір рішення (згадайте, що Шерлок Холмс сказав про те, що залишилося після усунення неможливого).

  • Експеримент : На цьому етапі спробуйте відтворити проблему на основі гіпотез, висунутих на попередньому кроці. Якщо ви серйозно думали на попередньому кроці, це повинно бути дуже очевидним. Іноді я "обманюю" і змінюю базу коду, щоб допомогти заданому тесту. Наприклад, я нещодавно розслідував збій, за яким я дійшов висновку, що він перебуває у стані гонки. Для того, щоб перевірити це, я просто помістив режим сну (500) між парою рядків коду, щоб дозволити іншому потоку робити його погані речі в "правильний" час. Я не знаю, чи це дозволено в "справжній" науці, але це цілком розумний код, яким ви володієте.

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


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

Я погоджуюсь, що це можна виправити досить багато. Я справді використовував сарказм у своїх словах "простий крок їх виправлення", але це не дуже вдало переходить у тип.

4

Спробуйте зменшити тестовий випадок. Коли він досить маленький, зазвичай простіше знайти відповідний код, що викликає проблему.

Цілком ймовірно, що нова реєстрація викликає проблеми, і попередня щоденна збірка була в порядку. У такому випадку ваш журнал змін з керування джерелом повинен допомогти вам вирішити, кого вловлювати.

Крім того, якщо ви перебуваєте на C / C ++, подумайте про запуск вальгринда або очищення, щоб виділити проблеми, пов'язані з пам'яттю.


2

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

  1. Перевірте свої лічильники. Використовуючи тестовий тон при відомій каліброваній напрузі, лічильник повинен прочитати "U" (коефіцієнт підсилення). Переклад: Якщо ваші інструменти зламані, ви не можете використовувати їх, щоб з’ясувати, що ще не так.
  2. Перевірте кожен компонент / етап посилення, працюючи назад від кінця. Використовуючи той самий тестовий тон, який застосовується до входу сцени, не повинно бути змін на виході сценки. Переклад: Ізолюючи кожен об'єкт від виходу назад, ми будуємо довіру до нашого коду, поки не знайдемо місце, де він псується. Якщо вашим інструментам знадобиться кілька шарів, щоб сигналізувати про проблему, вам потрібно знати, що шари між ними не сприяють цьому.

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

Тепер, коли я пережив важку частину виявлення моєї реальної проблеми, я напишу кілька тестів, щоб перевірити це на майбутнє.


2

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


2

Для більш практичного підходу:

  1. Якщо помилка пов’язана з необробленим винятком - подивіться слід стека. Нульова довідка, індекс поза межами і т. Д. Та ваші власні визначені винятки є найпоширенішими, ви можете призначити цю помилку молодшому розробнику, її, ймовірно, просто та добре навчанню.

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

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

  4. 80% всіх інших помилок вирішуються, маючи хороші системи ведення журналів та збираючи достатньо інформації для їх вирішення. Використовуйте вбудований трасування з декількома рівнями складних систем ведення журналів, таких як Log4Net / Log4J

  5. Помилки продуктивності - це категорія власна, правило гольдера тут - "вимірюйте спочатку, виправляйте пізніше!", і ви здивуєтеся, побачивши, скільки розробників просто здогадуються, де проблема, і вирушайте, щоб виправити це лише для того, щоб побачити пізніше зменшення часу відгуку на 3-4%.


Якби я міг поставити +1 кожному з цих 5 окремо, я б!
jmort253

1

У мене є два підходи:

  1. Розділіть задану проблему на менші частини, а потім підкоріть кожну меншу частину, слідуючи Divide and Conquerпарадигмі.
  2. Щоразу, коли я сумніваюся стосовно будь-яких значень, ніж я просто роздруковую значення змінних, щоб побачити, що саме надходить і виходить із змінної.

Такі підходи мені допомагали більшість разів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.