Как вы используете GDB для отладки кода?

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

Я делаю свою жизнь проще, используя IDE, которая интегрирует GDB! ;)

Dan 26.09.2008 19:47

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

Andrew Johnson 26.09.2008 19:52
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
12
2
5 211
7

Ответы 7

В общем, вы находите то, что не так, как должно быть, и работаете в обратном направлении, пока не поймете, почему.

Самый очевидный - самый полезный: установка точки останова на функции или номере строки и переход по коду строка за строкой.

Еще один полезный совет - иметь функции show для всех ваших структур / объектов, даже если они никогда не используются в вашей программе, потому что вы можете запускать эти функции из gdb:

gdb> p show_my_struct(struct)

My custom display of Foo:
   ...

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

gdb> watch foo
Watchpoint4: foo
gdb>

Почему бы просто не «p my_struct» вместо «p show_my_struct (my_struct)»?

sigjuice 25.03.2009 10:28

Поскольку вы можете декодировать поле флагов, запускать код проверки и т. д. Это не просто дамп значений структуры, вместо этого вы можете выгрузить значение, включая соответствующие объекты, на которые указывают. Например, если у obj1 есть список объектов obj2, вы можете вложить в него показ всех объектов obj2.

Andrew Johnson 08.04.2009 18:02

Некоторые подсказки:

  • используйте графический интерфейс (kdbg неплох, ddd, по крайней мере, лучше, чем gdb из командной строки, kdevelop имеет хороший интерфейс gdb, но имеет некоторые bgs, nemiver тоже выглядит неплохо, но все еще в разработке)
  • убедитесь, что у вас есть отладочные символы и исходный код для всех важных частей (ваш собственный код, а также некоторые системные библиотеки)
    • в RedHat вы можете установить пакеты -debuginfo, чтобы символы и исходный код волшебным образом появлялись в отладчике - действительно здорово, потому что вы можете просматривать вызовы функций libc и т. д.
    • в Debian / Ubuntu вы можете установить пакеты -dbg для получения символов; установка соответствующих исходных файлов для системных пакетов кажется сложной, хотя
  • Я обычно добавляю вызовы assert () и abort () в местах, которые не должны быть доступны, или в местах, которые я хочу изучить (какая-то тяжелая точка останова)
  • в идеале вызовы assert () или abort () должны быть заключены в какой-либо метод или макрос, который разрешает их только в выпусках отладки, или, что еще лучше, включает их только в том случае, если установлена ​​определенная переменная env
  • установить обработчик сигналов для SIGSEGV и SIGABRT; лично я проверяю, установлен ли определенный env var перед установкой обработчиков; и в обработчике я выполняю жестко запрограммированную внешнюю команду, которая обычно находится где-то в ~ / .local / bin /; эта команда может затем запустить kdbg и присоединить его к аварийному приложению. Вуаля, отладчик появляется в тот момент, когда ваше приложение делает что-то плохое.
  • Если вы используете модульные тесты, вы можете аналогичным образом подключить отладчик, когда тестовый пример не выполняется, чтобы затем проверить приложение.

На самом деле утверждения обычно удаляются при сборке без отладки (-g). Из ASSERT (3): «Если макрос NDEBUG был определен в момент последнего включения <assert.h>, макрос assert () не генерирует кода и, следовательно, ничего не делает».

David Holm 26.09.2008 20:25

Я не уверен, что назвал бы это «нормально». Обычно я сохраняю свои утверждения, и я также думаю, что сам факт использования макроса NDEBUG (в отличие, скажем, от отсутствия макроса «DEBUG») намекает на то, что разработчики assert согласились с тем, что утверждения обычно должны оставаться.

Thomas Padron-McCarthy 20.10.2008 02:14

Используйте ddd, визуальный интерфейс для gdb. Это позволяет вам легко делать что-то с помощью нескольких щелчков мыши и визуализировать, как работает код, плюс в консоли отладчика у вас есть интерактивный gdb.

Вы также можете использовать Geany.

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

Чтобы проверить аварийный дамп (или файл ядра, как его чаще называют), запустите GDB следующим образом:

gdb <program-name> <core-file>

Например:

gdb a.out core

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

Program terminated with signal 11, Segmentation fault.
#0  0x08048364 in foo () at foo.c:4
4         *x = 100;

В приведенном выше примере вы можете видеть, что программа завершилась из-за ошибки сегментации при попытке присвоить значение указателю. Набрав backtrace (или bt или where) в приглашении GDB, вы можете просмотреть полную трассировку программы:

(gdb) backtrace
#0  0x08048364 in foo () at foo.c:4
#1  0x0804837f in main () at foo.c:9

На этом этапе вы знаете, что main() с именем foo() и foo() потерпели крах в строке 4 при попытке присвоить значение *x. Часто это дает достаточно информации, чтобы вы могли исправить ошибку.

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

Я не уверен, насколько опытен OP, поэтому:

Документация GDB довольно приятная и всеобъемлющая. Первая глава - хорошее введение во все основы.

http://www.gnu.org/software/gdb/documentation/

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

Кроме того, Valgrind (http://valgrind.org/) действительно хорош / полезен для решения проблемы переполнения буфера и тому подобного (мне не повезло с GDB для этого.

Базовый, но очень полезный - используйте текстовый интерфейс с опцией -tui.

Вы можете активировать режим gdb tui с помощью CTRL-X CTRL-A

ciceron 27.02.2011 18:52

Другие вопросы по теме