16 Feb 2009 11:05 am

GDB: comandos básicos

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.

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply

You must be logged in to post a comment.