Отладчик GNU ( GDB ) — портативный отладчик , который работает во многих Unix-подобных системах и работает со многими языками программирования , включая Ada , Assembly , C , C++ , D , Fortran , Haskell , Go , Objective-C , OpenCL C , Modula . -2 , Pascal , Rust , [2] и частично другие. [3]
GDB был впервые написан Ричардом Столлманом в 1986 году как часть его системы GNU , после того как его GNU Emacs стал «достаточно стабильным». [4] GDB — это бесплатное программное обеспечение , выпущенное под лицензией GNU General Public License (GPL). Он был создан по образцу отладчика DBX , который входил в состав дистрибутивов Berkeley Unix . [4]
С 1990 по 1993 год его поддерживал Джон Гилмор . [5] Сейчас его поддерживает Руководящий комитет GDB, назначенный Фондом свободного программного обеспечения . [6]
GDB предлагает обширные возможности для отслеживания и изменения выполнения компьютерных программ . Пользователь может отслеживать и изменять значения внутренних переменных программы и даже вызывать функции независимо от нормального поведения программы.
Целевые процессоры GDB (по состоянию на 2003 год) включают: Alpha , ARM , AVR , H8/300 , Altera Nios/Nios II, System/370 , System 390 , X86 и его 64-битное расширение X86-64 , IA-64 «Itanium». , Motorola 68000 , MIPS , PA-RISC , PowerPC , SuperH , SPARC и VAX . Менее известные целевые процессоры, поддерживаемые в стандартной версии, включают A29K , ARC , ETRAX CRIS , D10V, D30V, FR-30, FR-V , Intel i960 , 68HC11 , Motorola 88000 , MCORE , MN10200, MN10300 , NS32K , Stormy16 и З8000 . (Более новые версии, скорее всего, не будут поддерживать некоторые из них.) GDB имеет встроенные симуляторы даже для менее известных целевых процессоров, таких как M32R или V850 . [7]
GDB все еще активно разрабатывается. Начиная с версии 7.0, новые функции включают поддержку сценариев Python [8] , а начиная с версии 7.8 также поддержку сценариев GNU Guile . [9] Начиная с версии 7.0, доступна поддержка «обратимой отладки», позволяющей откатить сеанс отладки назад, что очень похоже на перемотку вышедшей из строя программы, чтобы увидеть, что произошло. [10]
GDB предлагает «удаленный» режим, часто используемый при отладке встроенных систем. Удаленная работа — это когда GDB запускается на одной машине, а отлаживаемая программа — на другой. GDB может связываться с удаленным «заглушкой», которая понимает протокол GDB, через последовательное устройство или TCP/IP. [11] Программа-заглушка может быть создана путем связывания с соответствующими файлами-заглушками, поставляемыми с GDB, которые реализуют целевую сторону протокола связи. [12] В качестве альтернативы, gdbserver можно использовать для удаленной отладки программы без необходимости каким-либо образом ее изменять.
Тот же режим также используется KGDB для отладки работающего ядра Linux на уровне исходного кода с помощью gdb. С помощью KGDB разработчики ядра могут отлаживать ядро почти так же, как они отлаживают прикладные программы. Это позволяет размещать точки останова в коде ядра, пошагово выполнять код и наблюдать за переменными. В архитектурах, где доступны регистры аппаратной отладки, можно установить точки наблюдения, которые запускают точки останова при выполнении или доступе к указанным адресам памяти. Для KGDB требуется дополнительная машина, подключаемая к машине, подлежащей отладке, с помощью последовательного кабеля или Ethernet . Во FreeBSD также возможна отладка с использованием прямого доступа к памяти FireWire (DMA). [13]
Отладчик не имеет собственного графического интерфейса пользователя и по умолчанию использует интерфейс командной строки , хотя и содержит текстовый интерфейс пользователя . Для него было создано несколько внешних интерфейсов, таких как UltraGDB, Xxgdb, Data Display Debugger (DDD), Nemiver , KDbg, отладчик Xcode , GDBtk/Insight, Seer и графический интерфейс отладчика HP Wildebeest (WDB GUI). Такие IDE , как Codelite , Code::Blocks , Dev-C++ , Geany , GNAT Programming Studio (GPS), KDevelop , Qt Creator , Lazarus , MonoDevelop , Eclipse , NetBeans и Visual Studio , могут взаимодействовать с GDB. GNU Emacs имеет «режим GUD» и существуют инструменты для Vim (например, clown). Они предлагают возможности, аналогичные отладчикам, имеющимся в IDE.
Некоторые другие инструменты отладки были разработаны для работы с GDB, например детекторы утечек памяти .
GDB использует системный вызов с именем ptrace (это название является аббревиатурой от «трассировка процесса») для наблюдения и управления выполнением другого процесса, а также для проверки и изменения памяти и регистров процесса.
Точка останова реализуется путем замены инструкции по заданному адресу памяти другой специальной инструкцией. Выполнение инструкции точки останова вызывает SIGTRAP.
Рассмотрим следующий исходный код, написанный на C :
#include <stdio.h> #include <stdlib.h> #include <string.h> size_t foo_len ( const char * s ) { return strlen ( s ); } int main ( int argc , char * argv [] ) { const char * a = NULL ; printf ( "размер a = %lu \n " , foo_len ( a ) ); выход ( 0 ); }
Используя компилятор GCC в Linux , приведенный выше код необходимо скомпилировать с использованием -g
флага, чтобы включить соответствующую отладочную информацию в сгенерированный двоичный файл, что позволит проверить его с помощью GDB. Если предположить, что файл, содержащий приведенный выше код, называется example.c
, команда для компиляции может быть такой:
$ gcc example.c -Og -g -o пример
И теперь двоичный файл можно запустить:
$ ./example Ошибка сегментации
Поскольку код примера при выполнении генерирует ошибку сегментации , для проверки проблемы можно использовать GDB.
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Авторские права (C) 2011 Free Software Foundation, Inc. Лицензия GPLv3+: GNU GPL версии 3 или новее <https://gnu.org/licenses /gpl.html> Это бесплатное программное обеспечение: вы можете свободно изменять и распространять его. НЕТ НИКАКИХ ГАРАНТИЙ, в пределах, разрешенных законом. Для получения подробной информации введите «показать копирование» и «показать гарантию». Эта GDB была настроена как «x86_64-redhat-linux-gnu». Инструкции по сообщению об ошибках см.: <https://www.gnu.org/software/gdb/bugs/>... Чтение символов из /path/example...done. (gdb) запустить Стартовую программу: /path/exampleПрограмма получила сигнал SIGSEGV, ошибка сегментации. 0x0000000000400527 в foo_len (s=0x0) в example.c:7 7 return strlen (s); (gdb) напечатайте s $ 1 = 0x0
Проблема присутствует в строке 7 и возникает при вызове функции strlen
(поскольку ее аргумент s
равен NULL
). В зависимости от реализации strlen ( встроенной или нет) вывод может быть разным, например:
GNU gdb (GDB) 7.3.1 Авторские права (C) 2011 Free Software Foundation, Inc. Лицензия GPLv3+: GNU GPL версии 3 или новее <https://gnu.org/licenses/gpl.html> Это свободное программное обеспечение: вы свободно изменять и распространять его. НЕТ НИКАКИХ ГАРАНТИЙ, в пределах, разрешенных законом. Для получения подробной информации введите «показать копирование» и «показать гарантию». Эта GDB была настроена как «i686-pc-linux-gnu». Инструкции по сообщению об ошибках см.: <https://www.gnu.org/software/gdb/bugs/>... Чтение символов из /tmp/gdb/example...done. (gdb) запустить Стартовую программу: /tmp/gdb/exampleПрограмма получила сигнал SIGSEGV, ошибка сегментации. 0xb7ee94f3 в strlen() из /lib/i686/cmov/libc.so.6 (gdb) bt # 0 0xb7ee94f3 в strlen () из /lib/i686/cmov/libc.so.6 # 1 0x08048435 в foo_len ( s = 0x0 ) в example.c:7 # 2 0x0804845a в main ( argc = <оптимизированный вывод>, argv = <оптимизированный вывод> ) в example.c:14
Чтобы устранить проблему, переменная a
(в функции main
) должна содержать допустимую строку. Вот исправленная версия кода:
#include <stdio.h> #include <stdlib.h> #include <string.h> size_t foo_len ( const char * s ) { return strlen ( s ); } int main ( int argc , char * argv [] ) { const char * a = "Это тестовая строка" ; printf ( "размер a = %lu \n " , foo_len ( a ) ); выход ( 0 ); }
Перекомпиляция и повторный запуск исполняемого файла внутри GDB теперь дает правильный результат:
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Авторские права (C) 2011 Free Software Foundation, Inc. Лицензия GPLv3+: GNU GPL версии 3 или новее <https://gnu.org/licenses /gpl.html> Это бесплатное программное обеспечение: вы можете свободно изменять и распространять его. НЕТ НИКАКИХ ГАРАНТИЙ, в пределах, разрешенных законом. Для получения подробной информации введите «показать копирование» и «показать гарантию». Эта GDB была настроена как «x86_64-redhat-linux-gnu». Инструкции по сообщению об ошибках см.: <https://www.gnu.org/software/gdb/bugs/>... Чтение символов из /path/example...done. (gdb) запустить Стартовая программа: /path/example размер = 21 [Низший 1 (процесс 14290) завершился нормально]
GDB выводит вывод printf
на экран, а затем сообщает пользователю, что программа завершилась нормально.
Затем, когда GNU Emacs стал достаточно стабильным, что в общей сложности заняло около полутора лет, я начал возвращаться к другим частям системы.
Я разработал отладчик, который назвал GDB, который представляет собой символический отладчик для кода C, который недавно поступил в распространение.
Этот отладчик во многом соответствует духу DBX, отладчика, поставляемого с Berkeley Unix.