Obs.: Essa é uma cópiá do artigo de minha autoria disponível na Wiki C/C++ Brasil.
O GDB, GNU Debugger, é um depurador multi-linguagem, suportando C, C++, Pascal, Objective-C, etc e multi-plataforma, rodando em Linux, HP-UX, FreeBSD, Windows através do CygWin e outras. Á primeira vista (e somente à primeira vista) a interface do GDB, toda em modo texto, parece confusa e complexa. Composto de diversos comandos é complicado para um programador iniciante se adaptar ou se localizar (ainda que a documentação do GDB seja excelente). Existem muitas interfaces gráficas para o GDB, algumas integradas à IDEs como KDEvelop e Anjuta e outras de uso específico para o GDB como o DDD e ou KDBG. Entretanto, na maioria das vezes elas não fornecem todo o poder que o gdb oferece. Abaixo fiz listagem com os comandos mais comuns do GDB, com seu uso, exemplos, etc. A listagem abaixo contém o básico para começar a usar o GDB. É importante ressaltar, também, que esta listagem é ínfima se comparada a ampla gama de opções fornecidadas pelo GDB.
set args
Seta os argumentos para execução do aplicativo. Ex.:
(gdb) set args --debug --verbose
backtrace ou bt
Mostra a pilha de funções (frames) executadas pelo programa até o momento. Uma variação deste comando, passando a opção ‘full’, mostra um backtrace completo, incluindo as variáveis na stack. Ex.:
(gdb) bt #0 0xffffe410 in __kernel_vsyscall () #1 0x476a0620 in raise () from /lib/libc.so.6 #2 0x476a1c80 in abort () from /lib/libc.so.6 #3 0x476d4907 in __fsetlocking () from /lib/libc.so.6 #4 0x476da122 in malloc_usable_size () from /lib/libc.so.6 #5 0x476db762 in free () from /lib/libc.so.6 #6 0x080485fc in main () at furado.cpp:39
Ou
(gdb) bt full #0 0xffffe410 in __kernel_vsyscall () No symbol table info available. #1 0x476a0620 in raise () from /lib/libc.so.6 No symbol table info available. #2 0x476a1c80 in abort () from /lib/libc.so.6 No symbol table info available. #3 0x476d4907 in __fsetlocking () from /lib/libc.so.6 No symbol table info available. #4 0x476da122 in malloc_usable_size () from /lib/libc.so.6 No symbol table info available. #5 0x476db762 in free () from /lib/libc.so.6 No symbol table info available. #6 0x080485fc in main () at furado.cpp:39 teste = 0x804a008 "" ponteiro = 0x804a018 "H \004\b" naoUsado = 0x4778fff4 "\\ýxGòÕhG" memNew = 0x0 outropoint = 0x804a038 "" p = 0x804a050 "" naoInicializado = 1199112180
frame ou f
Muda para um determinado frame. Ex:
(gdb) f 4 #4 0x476da122 in malloc_usable_size () from /lib/libc.so.6
print ou p
Mostra o conteúdo de uma expressão. Por exemplo:
(gdb) print outropoint $2 = 0x8048600 "U\211åWVSèO"
display
Mostra o conteúdo de uma expressão cada vez que o programa para. Por exemplo:
(gdb) display ponteiro 1: ponteiro = 0x804a018 "" (gdb) n main () at furado.cpp:30 30 meuAdoravelLeak(); 1: ponteiro = 0x804a018 "" (gdb) n Breakpoint 4, meuAdoravelLeak () at furado.cpp:6 6 return (char *) malloc(10); (gdb) n 7 } (gdb) n main () at furado.cpp:32 32 outropoint = alocamem(20); 1: ponteiro = 0x804a018 ""
list ou l
Mostra o código fonte do programa referente ao ponto atualmente em execução. Por exemplo:
(gdb) l 10 free(ponteiro); 11 } 12 13 char* alocamem(int size) { 14 char* point = (char *)malloc(size); 15 return point; 16 } 17 18 int main(void) { 19 char *teste = new char[10];
kill ou k
Manda um SIGKILL para o processo sendo debugado.
(gdb) k Kill the program being debugged? (y or n) y
break ou b
Configura um breakpoint em um determinado ponto do código.
(gdb) b furado.cpp:20 Breakpoint 1 at 0x8048595: file furado.cpp, line 20.
next ou n
Executa o programa até a próxima linha, sem sair do frame atual.
(gdb) n 27 teste[10] = 'a';
step ou s
Executa o programa até a próxima linha.
(gdb) s 29 ponteiro = meuAdoravelLeak();
stepi ou si
Executa exatamente uma instrução.
(gdb) si meuAdoravelLeak () at furado.cpp:5 5 char *meuAdoravelLeak(void) { (gdb) si 0x08048535 5 char *meuAdoravelLeak(void) { (gdb) si 0x08048537 5 char *meuAdoravelLeak(void) { (gdb) si 6 return (char *) malloc(10); (gdb) si 0x08048541 6 return (char *) malloc(10);
É possível analisarmos exatamente em qual instrução estamos, através do comando disassemble:
(gdb) disassemble Dump of assembler code for function _Z15meuAdoravelLeakv: 0x08048534 <_Z15meuAdoravelLeakv+0>: push %ebp 0x08048535 <_Z15meuAdoravelLeakv+1>: mov %esp,%ebp 0x08048537 <_Z15meuAdoravelLeakv+3>: sub $0x8,%esp 0x0804853a <_Z15meuAdoravelLeakv+6>: movl $0xa,(%esp) 0x08048541 <_Z15meuAdoravelLeakv+13>: call 0x80483f8 <malloc@plt> 0x08048546 <_Z15meuAdoravelLeakv+18>: leave 0x08048547 <_Z15meuAdoravelLeakv+19>: ret End of assembler dump.
finish
Executa até o frame atual até o fim.
(gdb) s meuAdoravelLeak () at furado.cpp:6 6 return (char *) malloc(10); (gdb) finish Run till exit from #0 meuAdoravelLeak () at furado.cpp:6 main () at furado.cpp:32 32 outropoint = alocamem(20); Value returned is $1 = 0x804a028 ""
handle ou ha
Configura a maneira que o gdb deve lidar com os sinais. Para isto, devem ser informadas palavras-chave identificando como os sinais devem ser gerenciados. As palavras-chave aceitas são: pass/nopass: repassa ou não o sinal para o aplicativo sendo debugado. stop/nostop: retorna ou não o controle para o debugger. print/noprint: mostra ou não uma mensagem, se o sinal acontecer. Por exemplo:
(gdb) ha SIGALRM print nostop pass Signal Stop Print Pass to program Description SIGALRM No Yes Yes Alarm clock
info threads
Lista o id das threads conhecidas pelo depurador.
info break
Lista os breakpoints previamente configurados. Por exemplo:
(gdb) info break Num Type Disp Enb Address What 4 breakpoint keep y 0x080484fa in meuAdoravelLeak() at furado.cpp:6 breakpoint already hit 2 times 5 breakpoint keep n 0x080484fa in meuAdoravelLeak() at furado.cpp:6 6 breakpoint keep y 0x080484fa in meuAdoravelLeak() at furado.cpp:6 breakpoint already hit 2 times 7 breakpoint keep y 0x080484fa in meuAdoravelLeak() at furado.cpp:6 breakpoint already hit 2 times 8 breakpoint keep y 0x080484fa in meuAdoravelLeak() at furado.cpp:6 breakpoint already hit 2 times
info args
Lista os argumentos passados para o frame atual. Convém notar que se o programa for compilado com otimizações é possível que alguns argumentos sejam passados através dos registradores não sendo possível, neste caso, para o depurador obter os seus valores.
(gdb) s alocamem (size=20) at furado.cpp:14 14 char* point = (char *)malloc(size); (gdb) info args size = 20
thread
Muda o fluxo de depuração para uma determinada thread. O ID das threads pode ser obtido através do comando info threads. Por exemplo, para mudar para a thread 5: (gdb) thread 5.