Essa é uma revisão anterior do documento!
Para quem programa em ambiente Linux existe uma ferramenta de debug muito importante o software gdb. Ele permite realizar certos debug em programas C. Vamos a um exemplo de um Ola Mundo e abri-lo no gdb.
#include <stdio.h> int main() { printf("Ola mundo\n"); return 0; }
Para compilar com suporte a simbolos que o gdb precisa para realizar o debug.
gcc -g -o olamundo olamundo.c
Para entrar no gdb e necessário somente passar como parametro o nome do programa no nosso caso de exemplo seria o nome olamundo.
ricardobarbosa@isadora:~/dev/c/pilha$ gdb olamundo GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from olamundo...done. (gdb) (gdb) (gdb)
Iremos cair no prompt de comando do gdb. O gdb funciona como um médico analisando um paciente, o paciente no nosso caso e o programa olamundo. Outro conceito importante do gdb é o breakpoint. O que seria um breakpoint seguindo a tradução seria um ponto de parada ou ponto de interrupção, ou seja, criaremos um ponto de parada onde nos executaremos o programa e quando ele chegar naquele ponto de parada irá parar e esperar interação do usuário, para verificar o conteúdo de uma variavel ou visualizar endereços de memória, etc.
Vamos criar um breakpoint na função main.
(gdb) break main Breakpoint 1 at 0x400531: file olamundo.c, line 5. (gdb)
Agora iremos executar nosso programa e ver ele parar no breakpoint na função main.
(gdb) run Starting program: /home/ricardobarbosa/dev/c/pilha/olamundo Breakpoint 1, main () at olamundo.c:5 5 printf("Ola mundo\n"); (gdb)
podemos também visualizar o código do programa através do comando list.
(gdb) list 1 #include <stdio.h> 2 3 int main() 4 { 5 printf("Ola mundo\n"); 6 return 0; 7 } (gdb)
Para executar passo-a-passo temos dois comandos
Então executaremos a próxima instrução.
(gdb) next Ola mundo 6 return 0; (gdb)
Repare que ele executou e exibiu a mensagem ola mundo e mostrou a próxima instruçao de return 0 o qual indica sucesso. Se continuarmos dando next executaremos todo o programa e o mesmo será finalizado.
(gdb) next Ola mundo 6 return 0; (gdb) next 7 } (gdb) next __libc_start_main (main=0x40052d <main>, argc=1, argv=0x7fffffffdcd8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdcc8) at libc-start.c:321 321 libc-start.c: No such file or directory. (gdb)
Além da execução de instruções passo-a-passo podemos ver o contéudo de variaveis. Vamos utilizar o seguinte código para exemplificar isto.
(gdb) break main Breakpoint 1 at 0x4004f1: file olamundo2.c, line 5. (gdb) run Starting program: /home/ricardobarbosa/dev/c/pilha/olamundo2 Breakpoint 1, main () at olamundo2.c:5 5 int a=10; (gdb) n 6 int b=10; (gdb) print a $1 = 10 (gdb) print b $2 = 0 (gdb) n 8 c=a+b; (gdb) print b $3 = 10 (gdb) n 9 return 0; (gdb) print c $4 = 20 (gdb)
Existe alguns comandos para verificar variaveis.
O comando info variables“ para listar os nomes de todas as variaveis globais e estatica. O comando info locals para listar as váriaveis locais que estão atualmente na pilha. O comando info args para listar os argumentos passados para o programa. O comando info frame** exibe informações sobre a pilha
To read the memory at given addresses you should take a look at x
x/x $esp for hex x/d $esp for signed x/u $esp for unsigned etc. x uses the format syntax, you could also take a look at the current instruction via x/i $eip etc.
You need to use gdb's memory-display commands. The basic one is x, for examine. There's an example on the linked-to page that uses
gdb> x/4xw $sp
to print “four words (w ) of memory above the stack pointer (here, $sp) in hexadecimal (x)”. The quotation is slightly paraphrased.
Use: 1. bt - backtrace: show stack functions and args 2. info frame - show stack start/end/args/locals pointers 3. x/100x $sp - show stack memory Try using ddd. ddd manual
Ok. Maybe I elaborate a little. I use it like this.
compile my program with debug symbols:
gcc -g program.c -o program
run ddd:
ddd program
In gui you can do all sorts of things, view machine code, view memory, etc. . Look around. In manual there is also a section of examining stack. ddd provides good interface for you to examine C program
View stack: gdb> backtrace
View current stack frame: gdb> info frame
View arguments of current stack frame: gdb> info args
View local variable of current stack frame: gdb> info locals
Navigate to parent stack frame: gdb> frame 1