Должен ли отладочный код всегда оставаться на месте или добавляться только при отладке и удаляться при обнаружении ошибки?

35

Я, например, добавляю код отладки (например, операторы print) только когда пытаюсь найти ошибку. И как только я его нашел, я удаляю отладочный код (и добавляю тестовый пример, который специально проверяет эту ошибку). Я чувствую, что он загромождает реальный код и поэтому не имеет места там, если я не отлаживаю.

Как ты это делаешь? Вы оставляете код отладки на месте или удаляете его, если он устарел (о чем может быть трудно судить, когда это так)?

gablin
источник

Ответы:

30

Отладочные операторы печати должны быть удалены; однако, если вам нужно добавить их для отладки производственной проблемы, возможно, стоит подумать, достаточно ли у вас информации, вводимой в вашу среду ведения журналов. Информация о параметрах, условиях ошибки и т. Д. Может быть полезна позже, когда появится следующая ошибка. Использование хорошей среды ведения журналов, в которой можно динамически включать сообщения отладки или трассировки, может быть очень полезным в дикой природе.

Аларик
источник
5
+1 Прежде всего за упоминание о наличии разумной основы отладки. Если изначально это имеет место, и существуют различные уровни отладки, то, надеюсь, рабочий код может выполняться без вызова дорогостоящих процедур отладки, а код разработки может выполняться с любым уровнем проверки, который, как мы надеемся, будет зарегистрирован любым способом.
Orbling
1
Согласитесь с Orbling. И, кроме того, для отладочного кода, отличного от исключительно отображения информации, который оказал влияние на производительность или другую причину, не подходящую для производства. (например, Утвердить на результат функции, например, проверить результат сортировки), вы можете рассмотреть два режима построения цели. режим отладки и режим выпуска.
Зекта Чан
16

Код, добавленный специально для отладки, должен быть удален из производственного программного обеспечения.

Является ли это полным удалением или помещением в разделы условной компиляции (как в C / C ++ / C #), зависит от вас и вашего стандарта кодирования.

Есть ряд причин для этого:

  1. Могут быть последствия для безопасности, если этот код выполняется или кто-то может получить доступ к его выводу.
  2. Это может замедлить работу приложения.
  3. Это может сбить с толку других разработчиков, которые смотрят на код (или, собственно, на вас самих) через 6 месяцев.
ChrisF
источник
+1 для условной компиляции, но блоки комментариев будут работать на языках, которые их не поддерживают. Никогда не оставляйте его скомпилированным в выпуске prod, но иногда крайне неэффективно продолжать удалять его полностью каждый раз, когда вы хотите сбросить сборку релиза.
Билл
1
Я работал в средах, где код C / C ++ всегда компилировался с опциями отладки на случай, если необходимо отладить производственный код или проверить coredump. Иногда для этого всегда был готов к отладке мандат, требующий оставить операторы отладки, чтобы их можно было включить с флагом без перекомпиляции кода. Java всегда разрешает отладку, если для нее установлены опции JVM, поэтому для отладки вещей требуется относительно меньше подготовительной работы.
Михаил Шопсин
16

ChrisF и Alaric имеют действительные баллы; +1 за них. Я могу определить по крайней мере 5 различных типов кода отладки, который я использую.

  1. Использование журналов для сброса состояния системы в определенный момент времени.

    void function(...)
    {
        ...dump everything i know about.
    }
    
  2. Использование логов для выполнения контрольных точек.

    void function(...)
    {
        ...got here 1
        ...got here 2
    }
    
  3. Код, который фактически заставляет определенное условие быть верным, но нарушает нормальное поведение. Пример:

    • Предположим, у вас есть несколько журналов об ошибке, но вы не можете воспроизвести проблему. Вы можете попробовать написать код, который заставляет определенные переменные иметь определенные значения, которые соответствуют информации в журнале.
  4. Ведение журнала проверки - я бы классифицировал это как подробное ведение журнала, которое можно использовать для проверки правильности программного обеспечения, которое не следует включать в производство, например, для проверки отдельных шагов алгоритма.

  5. Регистрация операций - см . Пост Аларика . Это в значительной степени то, что я имею в виду под «ведением журнала операций».

1, 2 и 3 следует вынимать полностью. Что-то вроде 4 я бы наверное условно скомпилировал из кода. В течение 5 лет у Аларика была замечательная возможность динамически отключать журналы. Это может касаться точки ChrisF в его второй пули для большинства случаев.

Pemdas
источник
1
Это хорошее резюме. Однако было бы лучше, если бы вы могли правильно отформатировать его, заменив 1)… на 1.… (чтобы форматирование Markdown выбрало его в виде списков) и сделав отступ в примере кода на 8 пробелов (опять же, чтобы Markdown выбрал его в качестве примера). код в списке).
Конрад Рудольф
@ Конрад Рудольф: Готово.
Габлин
3

Это зависит от того, что делает код. Некоторый код, который используется для отладки, можно оставить как есть, а часть следует удалить.

Код, который проверяет правильность параметров в методе, не всегда полезен, когда код работает правильно, но его часто держат, чтобы убедиться, что код продолжает работать должным образом.

Иногда вы пишете код по-разному, чтобы упростить отладку кода, например, вычисление значения и помещение его в локальную переменную, а затем использование переменной в следующей строке, что позволяет легко проверить результат вычисления при пошаговом выполнении через код. Вы можете переписать код для непосредственного использования вычисленного значения, но стоимость использования локальной переменной настолько мала (если вообще существует), что нет причин для перезаписи кода. Кроме того, есть смысл оставить код неизменным после того, как вы его протестировали, всегда есть небольшой риск, что вы внесете ошибку при его изменении.

Код, который вы добавляете просто для отслеживания конкретной ошибки, часто может быть удален после того, как вы нашли ошибку.

Guffa
источник
2

Когда-то я использовал много кода для отладки. Я почти целиком ориентировался на Windows, поэтому было много этой функции вывода строки отладки, которую я не помню, как писать по буквам, поэтому я мог записать трассировку с помощью конкретной программы.

Некоторый отладочный код остался на месте, а именно то, что предназначалось для вложения вызовов. Однако, хотя вещь отладочной строки в производственной системе в основном не видна, все это было сделано при условной компиляции.

Однако реальность такова, что весь этот отладочный код был огромным усилием для чего-то, что в идеале обрабатывается другим способом - с использованием, конечно, отладчика. В то время я не был впечатлен отладчиком Borland C ++. Инструменты были там, но они слишком часто давали вводящие в заблуждение результаты, и использование отладчика без IDE (часто необходимого) означало запоминание сочетаний клавиш, что отвлекало от работы.

Единственный худший отладочный опыт - это GDB из командной строки.

Конечно, важно быть экспертом в работе с инструментами, которые вы используете каждый день, но отладка не должна быть тем, чем вы занимаетесь каждый день. Если вы используете отладчик так часто, у вас все в порядке с изучением десятков команд и / или сочетаний клавиш, что кажется мне немного красным флажком.

К тому времени, когда я работал в Visual Studio 7, стало ясно, что отладка может быть очень практичной и эффективной. Если вы можете выполнить отладку в Visual Studio (включая экспресс-выпуски), отладка очень проста. Без сомнения, если вы сможете найти подходящий интерфейс GUI / IDE, GDB также прост и эффективен, хотя я еще не выполнил этот поиск.

Также есть что сказать для модульного тестирования, с анализом покрытия с использованием gcov. Чем больше вы уверены в поведении ваших библиотек, тем менее глубокой должна быть ваша отладка - и тем реже вам понадобится отладчик. И написание юнит-тестов - это вполне разумная вещь, которой вы должны заниматься большую часть дня.

Неожиданно важный инструмент = cmake, инструмент сборки, который позволяет мне, между прочим, легко переключаться между сборкой для GCC и для VC ++. Таким образом, я могу проводить модульное тестирование и покрытие на основе gcov с помощью GCC, но легко переключаюсь на VC ++, чтобы использовать отладчик.

Steve314
источник
Отладчик может быть довольно бесполезным, если не опасным в многопоточных приложениях, но мне нравится ваш красный комментарий.
Пемдас
@Pemdas - у меня еще не было серьезных проблем, хотя многопоточность явно не подходит для отладчика. Несмотря на это, я думаю, что правильные инструменты, вероятно, являются лучшим решением, чем отладочный код в принципе. Было бы неплохо использовать инструмент статического анализа, который может определять условия гонки, взаимные блокировки, условия, когда два потока могут одновременно бороться за одну и ту же память / ресурс и т. Д. Я понятия не имею, что доступно по этим направлениям, хотя я знаю, что есть некоторые умные инструменты там. Кли, например - я не понимаю, но базовое описание звучит очень впечатляюще.
Steve314
«Я думаю, что правильные инструменты, вероятно, являются лучшим решением, чем отладочный код в принципе». Это опасное утверждение;). Было бы неплохо иметь инструменты, позволяющие выполнять некоторые анализы, но я беспокоюсь, что разработчики, особенно новички, начнут слишком зависеть от этих инструментов, как кто-то, кому нужно использовать калькулятор, чтобы выяснить, что такое 15% из 100.
Пемдас
Попасть в зависимость от инструментов, которые я еще не исследовал, кажется маловероятным. На вашем примере калькулятора, да, но я все равно буду использовать OpenOffice Calc, а не писать свою простую электронную таблицу. Есть время для отладки кода (даже с отладчиком - например, вашим собственным случаем создания причудливого условия), но если он выходит за рамки определенной точки, существующие инструменты выигрывают. И когда дело доходит до вычитания 15% из 115, я тоже буду использовать этот калькулятор - то, что многие люди дадут в качестве очевидного ответа (100), неверно. В многопоточности очевидно правильные ответы печально известны тем, что иногда оказываются неправильными.
Steve314
1

Мое мнение: код отладки, используемый для устранения ошибки в рассматриваемом коде, я обычно полностью удаляю. Код отладки, используемый для устранения ошибки, вызванной внешними силами, я обычно просто комментирую.

Лорен Печтель
источник
-1

Если ошибка связана с модульным тестированием или с внутренним кодом, код отладки может быть полностью удален. Но если ошибка из-за производства, код отладки лучше быть внутри тегов компиляции. Помещение его в теги компиляции поможет другим разработчикам понять, что этот код предназначен только для целей отладки.

Маной Р
источник
-1

Используйте TDD , чтобы в вашем тестовом коде всегда было место, где он даже поддерживается.

dukeofgaming
источник
как это отвечает на заданный вопрос?
комнат
Потому что TDD приводит вас к «отладке» или тестированию кода, который вам не нужно удалять.
Dukeofgaming
Я не следую извините. Как так?
комнат