Jumpi’s Notepad

My annotations about the life, universe and everything!!! ;)

Tutorial Basico de GDB

with 6 comments

O post de hoje sera dedicado a esse famoso debugger do mundo UNIX e que pode ser utilizado em ambiente windows tambem, sim… vamos tratar do GNU Debugger ou GDB, software muito util para fazer analises e encontrar erros decorrentes em nossos programas.

Claro que a intenção desse post é ser bem basico, passando apenas informações necessarias para a iniciação, caso alguem queira saber mais, existe uma documentacao excelente, um exemplo disso e o livro Debugging with GDB

Entao chega de conversa e vamos ao que interessa..

Primeiro caso: Compilando para debugar

Iremos utilizar como exemplo, um programa que conta de 0 a 10, como queremos debugar esse programa, para isso utilizamos o seguinte comando

[jumpi@painkiller testes]$ gcc -g contador.c

Com esse comando geramos um arquivo de saida (a.out), que vai conter as informações necessarias para o debugging

Agora e hora de debugar, na linha de comando digitamos:

[jumpi@painkiller testes]$ gdb a.out
GNU gdb Red Hat Linux (6.5-15.fc6rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-redhat-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1”.

(gdb)

Com esse comando, entramos em modo de debugging e o gdb nos apresenta o prompt onde entramos com os comandos necessarios para o debugging.

Hora de definir o breakpoint: no gdb, podemos utilizar numero de linha ou ate mesmo o nome da funcao na qual se deseja inserir o breakpoint, no nosso caso vamos definir um breakpoint na funcao main com o seguinte comando

(gdb) break main
Breakpoint 1 at 0x8048395: file contador.c, line 7.
(gdb)

E agora rodamos o programa dentro do debugger com o seguinte comando

(gdb) run
Starting program: /home/jumpi/testes/a.out

Breakpoint 1, main () at contador.c:7
7 for (i=0; i<=10; i++) {
(gdb)

E ele para exatamente na linha onde foi inserido o breakpoint, no caso como definimos por funcao, entao ele para na primeira linha da funcao, numericamente falando, na linha 7

Agora temos 2 comandos que podemos utilizar para verificar as informacoes, step e next, no caso, step vai fazendo passo a passo, ou seja, linha por linha e o next é utilizado quando desejo passar por subrotinas, no nosso caso vamos utilizar o step e ver o que acontece

(gdb) step
8 printf(“Numero :%d\n”,i);
(gdb) step
Numero :0
7 for (i=0; i<=10; i++) {
(gdb) step
8 printf(“Numero :%d\n”,i);
(gdb) step
Numero :1

Ele vai executando cada passo da funcao solicitada, como estamos dentro de um laco, ele executa o laco ate o seu termino.

Suponha que eu quero verificar o valor da variavel no momento, nesse caso como eu possuo apenas a variavel i, vamos imprimir o seu valor, eu posso utilizar o comando print ou display da seguinte maneira

(gdb) print i
$1 = 4
(gdb) display i
1: i = 4
(gdb)

No caso, com print ele mostra a variavel temporaria que armazena o resultado e com display ele mostra a variavel definida pelo usuario no codigo.

Podemos setar tambem o valor das variaveis com o comando set variable da seguinte maneira

(gdb) set variable i=20
(gdb) display i
2: i = 20
(gdb)

Segundo caso: Utilizando o gdb para analisar coredumps

Coredumps sao arquivos que contem a informacao sobre um determinado erro gerado quando um programa e executado e utilizando o gdb podemos descobrir qual a anomalia do nosso programa

[jumpi@painkiller testes]$ gcc -g contador.c

[jumpi@painkiller testes]$ ./a.out
Numero :(null)
Segmentation fault (core dumped)
[jumpi@painkiller testes]$

Isso significa que o programa gerou um erro e um coredump foi criado, quando verificamos o conteudo do diretorio procurando por core

[jumpi@painkiller testes]$ ls core*
core.6180
[jumpi@painkiller testes]$

Verificamos que o core foi criado, agora vamos utiliza-lo para servir como base de informacao para o nosso debugging no gdb

[jumpi@painkiller testes]$ gdb a.out core.6180
GNU gdb Red Hat Linux (6.5-15.fc6rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-redhat-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1”.

warning: Can’t read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6…done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out’.
Program terminated with signal 11, Segmentation fault.
#0 0x0077bf9b in strlen () from /lib/libc.so.6
(gdb)

Carregado o gdb com o arquivo de core, podemos utilizar o comando backtrace ou bt, para verificarmos as chamadas de funções e separarmos por frames

(gdb) bt
#0 0x0077bf9b in strlen () from /lib/libc.so.6
#1 0x0074e1ff in vfprintf () from /lib/libc.so.6
#2 0x007539c3 in printf () from /lib/libc.so.6
#3 0x080483b1 in main () at contador.c:7
(gdb)

Bem, no nosso caso eu verifico que tem um problema no frame 3, na linha 7, entao o comando frame seguido do numero do frame para verificar o que ocorre

(gdb) frame 3
#3 0x080483b1 in main () at contador.c:7
7 printf(“Numero :%s\n”,i);
(gdb)

E assim verifico que por descuido, coloquei um %s, onde era um %i…🙂

Bem, utilizei apenas uma pequena fração para demonstrar do que o GDB é capaz, ele pode ser muito util para uma serie de outras coisas, sem contar que existem muitos outros detalhes mais especificos que nao foram abordados aqui nesse post, porem espero que seja util a vocês tambem… Ate a proxima!!!🙂

No play: Cacophony – Speed Metal Symphony – 06: Desert Island

Written by jumpi

July 24, 2007 at 4:19 am

Posted in Programming

6 Responses

Subscribe to comments with RSS.

  1. Boa! Bem resumido e mesmo assim prático.

    Só faltou anexar o link para download do código-fonte, permitindo que o pessoal acompanhe melhor o seu debug. Talvez acrescentar o código-fonte no inicio/final do post era uma outra idéia.

    []’s

    maxphil

    October 9, 2008 at 4:56 pm

  2. Muito bom, abraço

    Rafael

    October 14, 2008 at 12:31 am

  3. Excelente resumo: soluciona a maioria dos problemas do dia-a-dia.

    Com algumas referências (como um GDB Cheat Sheet), o “post” seria referência absoluta para qualquer um.

    Muito obrigado!

    Ricardo

    August 5, 2009 at 11:39 am

  4. panda

    February 10, 2013 at 10:57 pm

  5. Muito bom, obrigado. o/

    Az

    October 1, 2015 at 9:31 am

  6. I was recommended this blog via my cousin. I’m no longer certain whether this publish is
    written by him as no one else realize such distinct approximately
    my problem. You are amazing! Thank you!

    lasertest

    October 24, 2015 at 12:32 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: