GDB - GNU Debugger
Um debugger ajuda o programador no processo de depuração
de erros de um programa.
Uma forma habitual de depurar erros num programa é, imprimir o valor
de certas variáveis e/ou certos comentários, de forma a localizar
e perceber o problema. Outra forma é usar um debugger. Neste
último caso o debugger oferece-nos uma série de potencialidades
tais como, parar a execução do programa num dado ponto, examinar
o conteúdo das variáveis, alterar o conteúdo das variáveis,...
Na prática o programador experiente usa a combinação
das duas técnicas anteriores.
Erros
Podemos dividir os erros dum programa em dois tipos:
- Erros de sintaxe: são erros na composição
dos componentes da linguagem. Por exemplo, esquecer ( ou ),...
- Erros de semântica: são erros no comportamento
e lógica do programa. Por exemplo, a instrução if(a=b)
não é provavelmente o que o programador pretende.
Os debuggers são usados para resolver erros do segundo tipo.
Executar o GDB
Compile o seu programa do seguinte modo:
gcc -g -o prog prog.c
A opção -g destina-se a instruir o gcc a produzir
informação de debugging para posterior utilização.
De seguida faça:
gdb
(gdb) file prog
O gdb lê o executável do programa em causa.
Utilizadores de emacs: Fazer M-x gdb <ENTER> e introduzir o
nome do executável no mini-buffer.
Nota: Em qualquer altura, pode utilizar o comando help para
obter ajuda dentro do gdb.
Executar um programa
A execução de um programa dentro do gdb é feita com
o seguinte comando:
(gdb) run <argumentos_linha_comandos>
Onde <argumentos_linha_comandos> são os argumentos que
o programa aceita normalmente na linha de comandos . Posteriormente veremos
como parar a execução num dado ponto (breakpoint) e como
executar uma instrução ou função de cada vez
(controlo de execução).
Listar o programa
Em qualquer altura podemos listar o código fonte de um programa usando
o comando list ou simplesmente l:
(gdb) list
Lista as 10 linhas seguintes do programa.
(gdb) list n
Lista as linhas de n-5 a n+4.
Utilizadores de emacs: A listagem do programa é feita pelo
próprio emacs os caracteres "=>" assinalam a linha em execução.
O GDB dá-nos a possibilidade de pararmos a execução
do programa em qualquer sítio de forma analisarmos a sua execução
em pormenor. O comando break ou simplesmente b, permite
assinalar uma linha do programa onde a execução deve parar.
Podemos indicar o nome da função onde o programa deve parar.
Por exemplo:
(gdb) break calcula
Breakpoint 1 at 0x8048499: file prog.c, line 15.
Indica que a execução deve parar no início da função
calcula. Podemos também indicar a linha em que o programa deve
parar:
(gdb) break 18
Breakpoint 2 at 0x80484af: file prog.c, line 18
Para saber quais os breakpoints que temos neste momento:
(gdb) info break
Para apagar um breakpoint:
(gdb) delete n
Onde n é o número do breakpoint. Se n
for omitido apaga todos os breakpoints. Existem ainda os comandos enable
e disable que permitem activar/desactivar breakpoints.
Existem comandos que nos permitem controlar a execução de
um programa:
- step: executa a linha actual e pára na linha seguinte.
No caso da linha actual ser uma chamada a uma função, pára
na primeira linha dessa função.
- next: igual ao step, no entanto, quando se trata de
uma chamada a uma função, executa essa função
até ao fim e pára na linha seguinte.
- finish: faz nexts até ao fim da função
em que se encontra.
- continue: continua a execução até ao próximo
breakpoint.
Mostrar valores de variáveis
Podemos ver o valor de qualquer variável do programa com o comando
print ou simplesmente p, por exemplo, supondo que estamos a
executar um programa onde existe uma variável x:
(gdb) print x
$1 = 50
$1 é uma referência que pode ser usada no futuro para consultar
valores anteriores da variável x. No caso da variável
ser um apontador e quisermos examinar o conteúdo da posição
de memória nela armazenada, teremos que usar o * tal como no C.
Ás vezes é útil poder ver o valor de uma variável
sempre que existe um breakpoint, é feito um next ou um
step. Para isso usamos o comando display:
(gdb) display x
1: x = 50
(gdb) step
1: x = 51
...
A variável é associada a um índice, no caso anterior
1.
Alterar valores de variáveis
Para alterar o valor duma variável basta usar a instrução
set, por exemplo:
(gdb) set (x=49)
A variável x passa a ter o valor 49.
Sair do GDB
Para sair do gdb usamos o comando quit.
Utilizadores de emacs: C-x 0
Exercício
O programa seguinte lê n inteiros n <= 20 e calcula
a sua média:
#include <stdio.h>
int media(int [],float);
main(){
int vec[20], n,i;
printf("\n Quantos números (max.20)?:);
scanf("%d",n);
for(i=0;i<n;i++)
scanf("%d",&vec[i]);
printf("\n A media é: %d\n",media(vec,n));
}
int media(int vec[],int n){
int i,s;
for(i=0;i>n;i++);
s+=vec[i];
s = s/n;
return s;
}
- Corrija eventuais erros de sintaxe e execute o programa.
- O comportamento do programa é o correcto? Use o gdb para
corrigir os restantes erros.
Poderá encontrar um guia de referência rápida para o
GDB aqui.
Jorge Coelho
- ISEP 2002