Чи є друк для консолі / stdout гарною стратегією налагодження?


11

Скажімо, у нас є така функція:

public void myStart()
{
    for (int i = 0; i<10; i++) myFunction(i); 
}


private int myFunction(int a)
{

    a = foo(a);
    a = bar(a);
    return a; 
}

private int foo(int a)
{
    //do something here

    //something gnarly here

    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

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

Перше, що будь-який програміст першого року - це друк для консолі / std, (навчившись друкувати Hello World, перш ніж навчитися користуватися налагоджувачем).

Наприклад, для налагодження цього коду вони можуть зробити наступне:

private int myFunction(int a)
{
    print("before foo: a=" + a); 
    a = foo(a);
    print("before bar: a=" + a);
    a = bar(a);

    return a; 
}

private int foo(int a)
{
    //do something here
    print ("foo step1: a=" + a); 

    //something gnarly here
    print ("foo step2: a=" + a + " someOtherValue="+ someOtherValue + " array.length= " + someArray.length()); 
    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Тепер вони запускають код, отримують великий консольний друк, за допомогою якого вони можуть простежити, де все йде не так.

Альтернативою, звичайно, є встановлення точок перерви та проходження коду в кожній точці.

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

Але недоліком є ​​те, що ваш код потім пронизується усіма цими твердженнями про друк, які потім потрібно видалити.

(Чи можливо, можливо, сказати налагоджувачу надрукувати в журнал лише певні значення? Точки точки розриву можна легко додавати або видаляти без фактичного зміни коду.)

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


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

7
Важливо навчитися користуватися налагоджувачами, однак, може траплятися багато ситуацій, коли налагодження printf - єдиний доступний метод налагодження.
whatsisname

Відповіді:


26

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

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

Отже, щоб відповісти на ваше конкретне питання. Так. Використання відбитків для відстеження виконання є хорошою та широко застосовуваною стратегією налагодження. Однак ...

Замість того, щоб використовувати оператори друку, подумайте про використання структури журналів. Рамки ведення журналів мають концепцію рівнів журналу, тому ви можете додати цілу купу повідомлень журналу, але вибрати рівень для кожного. Коли ваша програма працює у звичайних умовах, ваш рівень буде ПОМИЛОЮ або ПОПЕРЕДЖЕННЯМ, так що повідомляються лише про важливі речі. Однак, коли ви шукаєте код і вам потрібно зрозуміти потік виконання, ви можете змінити реєстратор на INFO або DEBUG, і тепер усі ті "друкуючі" заяви, які у вас уже є в коді, повідомлять про додаткову інформацію.

Використання рамки реєстрації ...

  1. після завершення не потрібно буде видаляти всі відбитки.
  2. відбитки, які ви залишите в коді, можуть допомогти вам або будь-якому іншому розробнику налагодити цей самий код у майбутньому
  3. ви зможете налагоджувати цей код у полі, не потребуючи його кожного разу перебудовувати лише для додавання відбитків, які ви видалили.
  4. ви зможете перенаправляти повідомлення в журнал куди завгодно, а не лише на консоль. Вони можуть перейти у файл, syslog, DB, socket ... тощо

Оновлення: Я щойно помітив, наприкінці ви запитували: "Чи можливо сказати налагоджувачу надрукувати в журнал лише певні значення". Залежно від того, який відладчик ви використовуєте. Багато сучасних налагоджувачів дозволяють вам визначити дію для виклику при попаданні точки перерви. У деяких (я це робив у VS та WinDbg) можна вказати «надрукувати це та відновити». Visual Studio називає їх "точками сліду" замість "точок перериву"


+1 для першого абзацу. Налагоджувачі та журнали вирішують дві дуже різні проблеми.
Blrfl

1
Але ви не згодні з тим, що залишення операторів журналу в коді погіршує його?
dwjohnston

1
залежить від того, який вигляд журналу ви залишите на місці. Я щойно знайшов і видалив це: "logger.error (" ЩО ")". В іншому випадку я ставлюсь до коду реєстрації так само, як і до решти свого коду. Відформатуйте, зробіть це красивим і зробіть інформативним. Так, розсипати заяву про друк будь-яким іншим рядком - це занадто багато, і були випадки, коли мені доводилося вдаватися до цього. Але в цілому наявність усього файлу 10-20 журналів (файли / класи мають достатній розмір і не є гігантськими) зовсім не погано.
DXM

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

1
@Izkata: все залежатиме від специфіки вашої конкретної помилки та від кількості реєстрації вашого коду. Справа, яку я намагаюся натрапити, - це те, що завжди є значення наявності операторів реєстрації та наявності їх на різних рівнях: ERR -> WARN ... -> DEBUG. Якщо вам потрібно більше для чогось дуже конкретного, обов'язково почніть додавати друковані заяви. Але моя відповідь тому, хто використовує "print" як протокол реєстрації, завжди перейде до рамки і почне використовувати це.
DXM

3

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

Переваги налагоджувачів:

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

Переваги журналу / друку:

  • Для цього не потрібна спеціальна збірка або конфігурація налагодження. Це завжди працює.
  • Може використовуватися для аналізу помилок, які важко відтворити і трапляються рідко
  • Може використовуватися для аналізу залежних від часу помилок, коли пауза, викликана налагоджувачем, може легко змусити помилку зникнути.
  • Дає вам постійну інформацію, яку ви можете проаналізувати у вільний час. Ви можете переходити вперед і назад між результатами в різних точках потоку програми.

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

1

Наприклад, друк до стандартного виводу може бути хорошою стратегією налагодження коду

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

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

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

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


3
цю публікацію досить важко читати (стіна тексту). Ви б не хотіли відредагувати його в кращій формі?
гнат

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