Introducao-ao-gdb

Introdução ao GDB

Você vai aprender

  • O que é o GDB.

  • Como compilar um programa que será lido pelo GDB.

  • Como usar algum dos principais comandos.

Pré-requisito

O que é o GDB?

GNU Debugger, mais conhecido com o GDB, é uma ferramenta de debugger, ou seja, podemos inspecionar nosso código com muito mais detalhe e encontrar problemas que não poderiam ser encontrados normalmente.

Por exemplo, muitos programadores ficam frustrados quando aparece o Segmentation Fault, pois é uma mensagem de erro que não significa muita coisa e não ajuda a dizer onde e porque aconteceu esse erro, é para isso que a ferramenta do GNU está aqui para nos ajudar.

A ferramenta pode ser usada para fazer debug em várias linguagens, neste caso, vamos usá-la em um programa feito na linguagem C.

Olhando o problema

Primeiro vamos olhar o trecho de código abaixo:

Ok, agora vamos compilar esse código normalmente, para compilarmos usamos:

ao rodarmos o nosso código recebemos esse erro:

Temos aqui um cenário bem comum quando estamos programando na linguagem C, deparamos com um Segmentation Fault, um erro que acontece quando nosso programa tenta acessar(ler ou escrever) em uma posição ilegal da memória.

Como dito anteriormente, essa mensagem de erro não nos ajuda muito a resolver o nosso problema, mas não se preocupe, o GDB pode nos auxiliar a resolver a nossa situação

Preparando o executável para o GDB

Antes de usarmos o GDB, precisamos de usar a diretiva na compilação do nosso programa em C. Antes de mais nada, você sabe o que é uma diretiva?

Resposta

No contexto que estamos, as diretivas de compilação, são opções extras que podemos passar para um compilador, na hora de gerar o executável binário do nosso código.

Neste caso, usaremos a diretiva '-g', que irá colocar informações de debug no código, baseado nos formatos nativos do sistema operacional. Em outras palavras, o nosso programa compilado terá informações que poderão ser lidas pelo GDB, sem isto, não é possível fazer o debug.

Então iremos compilar nosso código da seguinte maneira:

Agora, com o nosso executável pronto, podemos mandá-lo para o GDB, para rodarmos o GDB, usamos o comando"gdb" mais o nome do nosso executável gerado, logo, o comando será

Observação 1: podemos mudar o nome do nosso executável utilizando a diretiva '-o' e logo em seguida, passar o nome do executável, como no exemplo abaixo:

E então passar para o GDB:

Usando o gdb

Se você rodou o comando de execução do GDB corretamente, você deve ter caído em uma tela similar a esta

Não se assuste, seja bem vindo ao GDB. Observe que abaixo de todo esse texto de direitos autorais, temos uma mensagem dizendo

Isso mostra que o GDB conseguiu ler corretamente o nosso código compilado "a.out", e estamos pronto para fazer debug. Primeiramente vamos aprender a rodar nosso código, para isso utilizamos a palavra chave

Para rodar o código, fazendo isso, conseguimos o seguinte resultado:

Pílula

Se você estiver rodando algum código, onde existe uma entrada massiva de dados, podemos usar redirecionamento de entrada , junto ao comando run, desta forma: ``` run < pub.in ``` sendo pub.in o arquivo com a entrada de dados

Novamente recebemos a mesma mensagem, SIGSEGV é um sinal que sistemas POSIX recebem quando acontece alguma referência inválida a memória e além disso, o GDB também nos mostra o número e o conteúdo da linha que deu o problema:

Porém isso ainda não nos ajuda a saber qual é o problema, mas dentro do GDB, temos mais opções, podemos usar o comando

para montar a pilha de stack, de chamadas das funções e encontrar a sequência de chamadas que resultou nesse problema.

Ok, isso não nos ajudou muito, já que não estamos trabalhando com um código bem simples. Talvez o comando

possa nos ajudar, este comando irá para pedir ao GDB parar em uma linha de código durante a execução do mesmo, vamos pedir para ele parar a execução na linha que deu nosso problema, ou seja:

Pronto, agora vamos executar o nosso programa novamente, usando o comando run.

Com isso, temos o nosso código (ainda em execução) parado na linha que pedimos.

Pílula

Em vez de colocar um break para cada linha, você pode usar os comandos step e next para pular para a próxima linha de código, pesquise mais sobre estes comandos na documentação do GDB

Nosso próximo passo será pedir para o GDB imprimir o valor de uma variável nossa usando o comando print acompanhado do nome da variável que queremos imprimir, ou seja:

Vamos executar o comando:

Imprimindo o valor do ponteiro e da varíavel dentro do ponteiro, e encontramos que a mesma contem lixo de memória, indicando que a variável não foi iniciada corretamente, e este é o erro do código.

Podemos agora sair do GDB, usando o comando:

e corrigir o nosso código

Observação: dentro do GDB, podemos usar o comando help acompanhado de outro comando para saber mais opções em como usar este dentro do GDB. Observe o exemplo abaixo onde temos instruções em como usar o comando break:

Veja mais tutoriais do GDB

Documentação oficial do GDB

Tutorial mais avançado de GDB

Last updated