Домашняя страница проекта – http://www.gnu.org/software/gdb/
Устанавливаем сам отладчик:
# yum -y install gdb
Предположим, у нас есть файл myfirst.cpp
:
#include <iostream> int main () { // using namespace std; // using std::cout; using std::endl; std::cout << "Come up and C++ me some time."; std::cout << endl; std::cout << "You won't regret it!" << endl; return 0; }
Собираем его:
$ g++ myfirst.cpp -o myfirst.o
И запускаем отладчик:
$ gdb myfirst.o GNU gdb (GDB) Red Hat Enterprise Linux (7.2-64.el6_5.2) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/setevoy/scripts/cpp/prata/myfirst.o...(no debugging symbols found)...done. (gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Come up and C++ me some time. You won't regret it! Program exited normally. Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6_5.2.x86_64 libgcc-4.4.7-4.el6.x86_64 libstdc++-4.4.7-4.el6.x86_64
Посмотреть доступные команды можно с помощью help
в интерфейсе самого отладчика:
(gdb) help List of classes of commands: aliases -- Aliases of other commands breakpoints -- Making program stop at certain points data -- Examining data files -- Specifying and examining files internals -- Maintenance commands obscure -- Obscure features running -- Running the program stack -- Examining the stack status -- Status inquiries support -- Support facilities tracepoints -- Tracing of program execution without stopping the program user-defined -- User-defined commands Type "help" followed by a class name for a list of commands in that class. Type "help all" for the list of all commands. Type "help" followed by command name for full documentation. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous.
Кроме того, gdb
сообщает, что:
Missing separate debuginfos
Для их установки нам понадобится утилита debuginfo-install
, которая входит в набор yum-utils
:
# yum -y install yum-utils
Теперь устанавливаем сами пакеты:
# debuginfo-install glibc-2.12-1.132.el6_5.2.x86_64 libgcc-4.4.7-4.el6.x86_64 libstdc++-4.4.7-4.el6.x86_64
Если получаем сообщение вида:
... Could not find debuginfo for main pkg: glibc-2.12-1.132.el6_5.2.x86_64 Could not find debuginfo pkg for dependency package glibc-2.12-1.132.el6_5.2.x86_64
Значит не подключён репозиторий Debuginfo
.
Редактируем файл /etc/yum.repos.d/CentOS-Debuginfo.repo
, и меняем:
enabled=0
на
enabled=1
Проверим нашу программу и gdb
ещё раз:
$ gdb myfirst.o GNU gdb (GDB) Red Hat Enterprise Linux (7.2-64.el6_5.2) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/setevoy/scripts/cpp/prata/myfirst.o...(no debugging symbols found)...done. (gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Come up and C++ me some time. You won't regret it! Program exited normally.
Обратите внимание на сообщение (no debugging symbols found)
.
Что бы получать полную информацию от отладчика, нам необходимо перекомпилировать проект так, чтобы его двоичный файл содержал отладочную информацию. Эта информация включает в себя, в частности, описание соответствий между адресами исполняемого кода и строками в исходном коде.
Запускаем компилятор g++
с опцией -g
:
$ g++ myfirst.cpp -o myfirst.o -g
И нова запускаем gdb
:
$ gdb myfirst.o GNU gdb (GDB) Red Hat Enterprise Linux (7.2-64.el6_5.2) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/setevoy/scripts/cpp/prata/myfirst.o...done. (gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Come up and C++ me some time. You won't regret it! Program exited normally.
Что бы посмотреть исходный код программы – выполните команду list
:
(gdb) list 1 #include <iostream> 2 3 int main () { 4 // using namespace std; 5 // using std::cout; 6 using std::endl; 7 8 std::cout << "Come up and C++ me some time."; 9 std::cout << endl; 10 std::cout << "You won't regret it!" << endl;
Команда будет выведена не вся, а только первые 10 строк кода.
Для продолжения просмотра кода – просто ещё раз укажите list
:
(gdb) list 3 int main () { 4 // using namespace std; 5 // using std::cout; 6 using std::endl; 7 8 std::cout << "Come up and C++ me some time."; 9 std::cout << endl; 10 std::cout << "You won't regret it!" << endl; 11 return 0; 12 }
Зададим точку остановки, с которой мы будет проверять работу программы:
(gdb) break 8 Breakpoint 1 at 0x400818: file myfirst.cpp, line 8.
Запустим программу на выполнение в дебаггере:
(gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Breakpoint 1, main () at myfirst.cpp:8 8 std::cout << "Come up and C++ me some time.";
Остановка выполнена на 8 строке.
Просмотреть список точек остановки:
(gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400818 in main() at myfirst.cpp:8 breakpoint already hit 1 time
Удалить точку:
(gdb) delete 1
Зададим новую точку:
(gdb) break 11 Breakpoint 4 at 0x400852: file myfirst.cpp, line 11. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Come up and C++ me some time. You won't regret it! Breakpoint 4, main () at myfirst.cpp:11 11 return 0;
Пройдём по шагам выполнения программы.
Создадим точку:
(gdb) list 1 #include <iostream> 2 3 int main () { 4 // using namespace std; 5 // using std::cout; 6 using std::endl; (gdb) break 6 Breakpoint 5 at 0x400818: file myfirst.cpp, line 6.
Запускаем:
(gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Breakpoint 5, main () at myfirst.cpp:8 8 std::cout << "Come up and C++ me some time.";
И делаем шаг:
(gdb) step std::operator<< <std::char_traits<char> > (__out=..., __s=0x4009a8 "Come up and C++ me some time.") at /usr/src/debug/gcc-4.4.7-20120601/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/ostream:505 505 operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
Тут мы, например, видим как вызывается класс char_traits
.
Или так:
(gdb) s 507 if (!__s)
Чтобы при вызове функции программа не входила в неё, а продолжала дальше выполняться только на текущем уровне стека, вместо step
даётся команда next
или просто n
:
(gdb) run Starting program: /home/setevoy/scripts/cpp/prata/myfirst.o Breakpoint 1, main () at myfirst.cpp:8 8 std::cout << "Come up and C++ me some time."; (gdb) n 9 std::cout << endl; (gdb) n Come up and C++ me some time. 10 std::cout << "You won't regret it!" << endl; (gdb) n You won't regret it! 11 return 0; (gdb) n 12 } (gdb) n __libc_start_main (main=0x400814 <main()>, argc=1, ubp_av=0x7fffffffe088, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x7fffffffe078) at libc-start.c:258 258 exit (result); (gdb) n Program exited normally.
Ссылки по теме
http://www.cs.cmu.edu
http://www.gnu.org