Uma coleção de resumos, para ajudar os que precisam daquele empurrão.
O gdb é o debugger de facto para C/C++ em linux. Permite inspecionar o que um programa esta a fazer num certo ponto de execução, inspecionar o valor das variaveis naquele momento, entre muitas outras coisas.
Usamos o gdb, ou qualquer outro debugger, para:
Para usar o gdb é preciso includir uma flag extra quando compilamos o nosso código com o gcc. A flag em questão é -g. Desto modo o gcc sabe que é para compilar o programa em debug mode e includi informação extra no executavel.
Um exemplo com mais flags à mistura.
gcc -g code.c
Para usar o gdb é simples, assumindo que o terminal se encontra na diretoria do executavel:
gdb nome_do_executavel
O gdb possui uma shell interativa com um conjunto de comandos bastante completos.
O terminal do gdb tem TAB completion para maior parte dos comandos e help <comando> para mais informações sobre qualquer comando.
Para executar o programa:
(gdb) run
Assumindo que o programa tem erros, a linha que levou o programa a crashar é apresentada após correr o programa juntamente com mais alguma informação.
Se suspeitarmos que uma instrução é a culpada podemos mandar para o programa antes de a executar. Para isso impomos breakpoints. O programa para de executar ANTES de executar a instrução do breakpoint.
Para colocarmos um breakpoint na linha 20:
(gdb) break 20
Ou simplesmente
(gdb) b 20
Se o nosso programa tiver vários ficheiros .c associados temos que especificar o ficheiro:
(gdb) b random.c:20
Podemos também por um breakpoint associado a uma função diretamente:
int test(char a, void* c){
// codigo
}
(gdb) b test
Agora que temos vários breakpoints quando corrermos o programa com run ele vai parar no primeiro breakpoint que encontrar.
Podemos continuar para o próximo com o comando continue, ou executar o programa linha a linha com o comando step.
Semelhante ao step existe o next, que trata uma função (por exemplo) como uma linha de código só, executando-a e parando depois.
Estar sempre a escrever step ou next é repetitivo, ao carregar no ENTER o gdb executa o ultimo comando outra vez.
Para remover um breakpoint podemos usar o comando del <num> onde num é o número do breakpoint. del apenas remove todos os breakpoints
As vezes é interessante estudar o estado das nossas variáveis.
O comando print seguido de uma variável, imprime o valor da mesma.
(gdb) print var
É possível formatar este valor para outra base numérica.
Estar sempre a verificar o estado de uma variável a mão também é aborrecido e o gdb oferece duas alternativas.
O comando display repete o print sempre que o gdb pára, ou seja, quando para num breakpoint, no fim de um next ou step.
(gdb) display var
Para parar de fazer display a uma variável basta fazer undisplay <num> onde o num é indicado atrás do valor da variável impressa.
O comando watch é uma espécie de breakpoint que interrompe a execução do programa quando a variável que esta a ser observada é alterada, fazendo print do novo e antigo valor.
(gdb) watch var
Atenção que se várias variáveis tiverem o mesmo nome o gdb escolhe qual observar por localidade.
Porque a preguiça não tem limites, os commandos mais utilizados tem uma abreviatura disponível:
| comando | abreviatura |
|---|---|
break |
b |
print |
p |
run |
r |
next |
n |
step |
s |
continue |
c |