Что Ваш фаворит отлаживают методы в C++? [закрытый]

Я думаю, что необходимо смочь считать имя/значение в Вашем ПОЛУЧАТЬ массив. Я думаю, что кнопка, которая не была нажатой привычкой, появляется в том списке.

6
задан Martin Beckett 26 August 2009 в 03:19
поделиться

20 ответов

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

0
ответ дан 8 December 2019 в 02:02
поделиться

Режим Emacs gud-gdb - это армейский швейцарский нож!

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

IDA PRO - это еще одна вещь, я тоже могу использовать ее время от времени. время, когда дело доходит до (RE)

0
ответ дан 8 December 2019 в 02:02
поделиться

Если вы используете отладчик Visual Studio (я подозреваю, что вы это делаете, поскольку вы упомянули «редактировать и продолжить»), вы можете эффективно использовать «Немедленное окно». Вы можете быстро вызвать его с помощью сочетания клавиш Ctrl + Alt + I

«Немедленное окно» довольно близко похоже на цикл «Чтение-Оценка-Печать», который является обычным для динамических языков, но почти отсутствует в C ++ и подобные языки. Непосредственное окно позволит вам оценивать простые выражения, которые вы также можете делать в окне наблюдения, но также позволяет вам запускать простые операторы, для которых окно наблюдения не так хорошо.

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

Отладка таким способом имитирует инкрементный стиль программирования, популярный в языках, предлагающих REPL. прямо из коробки (например, Python или Ruby). Это может быть весьма полезно при отладке.

Такой способ отладки имитирует инкрементный стиль программирования, популярный в языках, которые предлагают REPL из коробки (например, Python или Ruby). Это может быть весьма полезно при отладке.

Такой способ отладки имитирует инкрементный стиль программирования, популярный в языках, которые предлагают REPL из коробки (например, Python или Ruby). Это может быть очень полезно при отладке.

0
ответ дан 8 December 2019 в 02:02
поделиться

Пишу осторожно, поэтому я в первую очередь минимизирую создание ошибок.

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

Printfs - чрезвычайно мощный инструмент, но по-прежнему оружие последней инстанции.

0
ответ дан 8 December 2019 в 02:02
поделиться

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

1
ответ дан 8 December 2019 в 02:02
поделиться

Утверждения. Когда я пишу код, если я замечаю какие-либо крайние случаи, которые, по моему мнению, могут указывать на проблему, я могу добавить строку, которая сообщит мне в отладочных сборках, если такое происходит. За бонусные баллы они не влияют на производительность сборок выпуска, поэтому вы можете проверить полудорогие вещи, например, assert (someMap.find (someKey)! = SomeMap.end ());

Очевидно, они не заменяют проверку реальных условий ошибки, которые вы должны уловить, но они отлично подходят для таких крайних случаев когда вы думаете: «Может, мне стоит это проверить?», пока пишете код.

1
ответ дан 8 December 2019 в 02:02
поделиться

ASSERTs ASSERTs.

У меня есть 300000 loc (не считая комментариев) сильно разложенного и повторно используемого кода в моих личных библиотеках, из которых около 15% (предположение) - шаблоны, а 50000 loc - тестовый код.

Если идиома дублируется, то она сделана функция / метод. Лично я рассматриваю простоту вырезания и вставки, поскольку изобретение DEVIL намеренно помещено туда, чтобы раздувать код и распространять дефекты.

Около 4% библиотеки - это ASSERTS и отладочный код (очень мало printfs и почти весь вывод является поставленный в очередь вывод в настраиваемую задачу с низким приоритетом потока cout, потому что ввод-вывод экрана настолько дорог и, следовательно, меняется время). Возможно, 50% утверждений предназначены для гарантии инвариантов класса и условий публикации при выполнении метода.

Я беспощадно реорганизовываю код, когда пересматриваю фрагмент кода, который я мог поспешить или, может быть, просто сделал ошибку в дизайне связи интерфейса / объекта, например, объект-субъект метода действительно принадлежит как объект-объект, а метод принадлежит к один из исходных объектов-объектов (объектов-параметров). Либеральный подход к утверждениям, кажется, защитит меня от некоторых глупых ошибок, если я сделаю существенный рефакторинг. Это случается редко, но бывают случаи.

У меня есть макрос DEBUGGING, который действует так же, как ASSERT, поэтому я могу иметь код, окруженный

DEBUGGING (... code ....);

и он не компилируется в неотладочных сборках.

Я не использую assert, поставляемый поставщиком. Мои утверждения НЕ прерывают работу и дамп ядра, они просто вызывают окно сообщения и вызывают отладчик. Если это новый код, а метод - метод const, возможность вернуться к методу, а затем повторно выполнить его (метод) с тем же набором параметров, очень полезна. Иногда даже тот факт, что некоторые данные изменены, не имеет отношения к проблеме, и можно повторно вызвать их с получением знаний.

Я абсолютно НЕНАВИЖУ отладчики командной строки. Это как вернуться на 25 лет назад - с таким же успехом можно использовать телетайп и линию со скоростью 2400 бод. Мне нужна полноценная IDE, в которой можно щелкнуть правой кнопкой мыши по структуре данных и открыть ее, закрыть, выполнить поиск указателей, выполнить методы и т. Д. И т. Д.

Я просматриваю каждую строку моего нового кода и проверяю каждую из моих) переменных для ожидаемого поведения. Здесь бесценно использование IDE, выделяющего изменения. Для этого с GDB нужно быть концертным пианистом, помнящим Карнака Великолепного ;-).

Для новых разработок я также пытаюсь захватить данные потока / данные сообщений при возникновении ненормального состояния. Это особенно полезно для серверов udp и часто дает фору воспроизводимости.

Мне также нравятся симуляторы, которые могут «окружать приложение, управлять им, потреблять от него и выполнять проверку» (объединенные / связанные симуляторы источника / приемника). ) Почти весь мой код безголовый или, по крайней мере, взаимодействие человека не имеет отношения к функциональности, поэтому часто возможно "окружение" приложения. Я считаю очень важным иметь хорошую поддержку и руководство, которое понимает, что создание тестовых данных очень важно а сбор тестовых данных - это то, что складывается в набор тестов, которые могут развиться в комплексный регрессионный / дымовой тест.

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

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

18
ответ дан 8 December 2019 в 02:02
поделиться

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

1
ответ дан 8 December 2019 в 02:02
поделиться

Прослеживание, изменение переменных в памяти для попадания в какую-то непонятную ветвь кода. Редко редактируйте и продолжайте, по какой-то причине я не могу полностью доверять ему в поддержании нормального состояния, поэтому после изменения выполняется полное выполнение.

Когда невозможно отследить (например, gdb в Windows слишком медленный, для достижения точки останова требуется 30 секунд каждый раз), затем printf. Нежелательный код и сбрасывает время в случае ошибок многопоточности, но иногда это единственный выход.

Отладчики дизассемблера при отладке сборок выпуска без отладочной информации (Olydbg хорош, когда он работает).

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

Отправка трассировки стека сбоев домой еще приятнее.

Утверждения распространяются там, где это необходимо.

Минидампы для сбоев на машинах пользователей.

1
ответ дан 8 December 2019 в 02:02
поделиться

Занимаясь многопоточностью, я не мог жить без регистрации. Для ведения журнала в C ++ я использую библиотеку templog . Он позволяет несколько уровней серьезности ( насколько это плохо? ) умножить на несколько целей журнала (, кому это может быть интересно? ) в сочетании с таким же количеством приемников журнала фильтрации ( куда писать в? ) как хотите, чтобы не утонуть в шуме. Он имеет большое значение для повышения эффективности, используя мета-шаблон, чтобы помочь компилятору избавиться от лишнего кода, не попадая в ловушку assert (do_something_important ()) .

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

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

2
ответ дан 8 December 2019 в 02:02
поделиться

Я голосую за gdb. Особенно, когда все, с чем вам нужно работать, - это файл ядра.

printf удобны, когда вы имеете общее представление о том, где находится ошибка. Но когда группа тестирования вернется к вам с файлом ядра и странным описанием проблемы, возможность анализа дампа ядра даст вам огромную фору в ваших усилиях по отладке.

2
ответ дан 8 December 2019 в 02:02
поделиться

Мне нравится gdb - обычно я использую его в режиме командной строки, но, если вы этого не выносите, для него есть интерфейсы с графическим интерфейсом, например Insight , Ddd и т. Д. Журналы тоже всегда помогают, как и файлы дампа ядра, для которых вы можете выполнить «посмертную отладку» с помощью тех же инструментов.

5
ответ дан 8 December 2019 в 02:02
поделиться

Реактивные меры:

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

  • Тактика отладки. Знакомство с вашими инструментами. Знание распространенных ошибок. Процесс дедукции. Использование гипотез и разветвлений по различным идеям ... возвращение к предыдущим идеям при необходимости. Отслеживание прогресса отладки. Научный метод.

  • Аналитические инструменты (например, Dependancy Walker , .NET Reflector ), дампы памяти, трассировки стека и журналы.

Профилактические меры:

  • Небольшие дополнительные строит. Во время активной разработки добавляйте в свой проект по частям и тестируйте каждую входящую часть. Не выкладывайте кучу кода, а затем смешивайте Run и беспечно исправляйте каждую ошибку. Добавляйте в свою программу по частям и не торопитесь, чтобы все исправить. Постарайтесь сделать каждое приращение в вашем проекте «атомарным».

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

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

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

6
ответ дан 8 December 2019 в 02:02
поделиться

В общем, printf's. Они позволяют легко нарезать программы и не требуют никаких инструментов, кроме редактора и компилятора.

8
ответ дан 8 December 2019 в 02:02
поделиться

Многоуровневые системы регистрации. Я использую как минимум 5 уровней:

  • подробный : вещи, которые вы хотите видеть только при отладке низкоуровневых вещей, таких как ошибки протокола; могут быть скомпилированы из двоичных файлов выпуска, поэтому вы можете поместить на этот уровень вещи, которые не хотите, чтобы конечные пользователи находили

  • internal : трассировка более низкого уровня, чем нормальный уровень, что часто бывает полезно, но не так часто, что вы хотите видеть это все время

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

  • проблема : ошибки времени выполнения, которые программа знает, как справиться; вы можете выбрать запуск на этом уровне для выпускных версий вместо нормальной

  • фатальной ошибки : сообщения типа «крикни и умри», наподобие нехватки памяти

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

13
ответ дан 8 December 2019 в 02:02
поделиться

При написании кода подумайте, как вы собираетесь размещать там точки останова позже. В частности, это означает не переусердствовать с вызовами вложенных функций - foo (bar (baz)) - и то же самое для цепочек полей / методов - foo (). Bar (). Baz () . В общем, если выражения не являются тривиальными, часто имеет смысл помещать их в отдельные строки и назначать их переменным, даже если значения используются только один раз - затем вы можете легко пройти через каждое, установить точку останова точно там, где вы хотите, и у вас будут значения в окне просмотра. При компиляции с оптимизацией любые такие переменные, вероятно, будут оптимизированы, особенно если вы используете трюк с константной ссылкой вместо того, чтобы полагаться на RVO.

-1
ответ дан 8 December 2019 в 02:02
поделиться

все виды отслеживания

0
ответ дан 8 December 2019 в 02:02
поделиться

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

0
ответ дан 8 December 2019 в 02:02
поделиться

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

Это особенно полезно с устаревшим кодом, когда нынешние разработчики не знают всех областей кода. Это помогает сузить область поиска и код, который необходимо проанализировать. Это действительно требует наличия хорошей регистрации / трассировки.

Это работает, когда у вас есть успешный вариант использования, а другой - неудачный. Например, функция X раньше работала в версии 3 вашего продукта, но теперь не работает в версии 4, и никто не знает почему.

Сравните журналы, используйте awk или sed для исключения избыточных различий (эти сценарии можно использовать повторно):

  • Отметки времени
  • ID потоков - иногда фильтрация по определенному потоку
  • пути
  • и т. Д.

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

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

1
ответ дан 8 December 2019 в 02:02
поделиться

Я использую команду gdb command для создания операторов printf на лету. Просто убедитесь, что последняя команда - continue.

#assume two breakpoints, 1 and 2
commands 1
  silent
  echo calling baz\n
  set $print_foobar=1
  continue
end

commands 2
silent
  echo calling foobar\n
  if $print_foobar
    set $print_foobar=0
    backtrace
  end
  continue
end

Недавно я влюбился в эту технику, поскольку она позволяет мне создавать оператор printf () для уже выполняемого кода. Кроме того, сценарии GDB, хотя и ограниченные, позволяют вам многое сделать при принятии решения, что печатать. Я еще не встречал ситуации, когда раздел команд был бы не так хорош или лучше, чем printf () .

Кроме того, сценарии GDB, хотя и ограниченные, позволяют вам многое сделать при принятии решения, что печатать. Я еще не встречал ситуации, когда раздел команд был бы не так хорош или лучше, чем printf () .

Кроме того, сценарии GDB, хотя и ограниченные, позволяют вам многое сделать при принятии решения, что печатать. Я еще не встречал ситуации, когда раздел команд был бы не так хорош или лучше, чем printf () .

3
ответ дан 8 December 2019 в 02:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: