Página
GDB: comandos básicos
Obs.: Essa é uma cópia do artigo de minha autoria disponível na antiga 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