Utilização do debugger

Utilização do debugger

Para utilizar o debugger, tem que se compilar o código com a opção -g

gcc -Wall -Wextra -ansi -pedantic -O2 -g *.c -o executavel

A maneira mais simples é colocar essa opção na variável CFLAGS na makefile. Para utilizar é só escrever no prompt:

gdb executavel

E usar alguns dos comandos dados a seguir.

Lista de comandos

p expressão
Imprime a expressão
b linha
Coloca um breakpoint numa linha no ficheiro actual
b ficheiro:linha
Coloca um breakpoint numa linha do ficheiro
b nome_de_função
Coloca um breakpoint numa função
run
Corre o programa desde o início
c ou cont
Continua a execução do programa
s ou step
Executa uma linha
n ou next
Executa uma linha mas não entra em funções auxiliares
where
Mostra o stack trace (útil se o programa rebentou por exemplo)
l ou list
lista o código perto da posição actual onde está a ser executado
up
subir na stack
down
descer na stack
cond número_do__breakpoint condição
Só pára no breakpoint que foi definido com o comando b quando a condição é verdade

 

Descobrir porque é que o programa crashou

Se o programa crashou (e.g. segmentation fault) o mais fácil é fazer o seguinte:

  1. Compilar o programa como mostrado acima
  2. Antes de correr o programa escrever no prompt ulimit -c unlimited (pode-se adicionar esta linha ao ~/.bashrc para não termos que fazer isto de cada vez)
  3. Correr o programa e fazer com que ele estoure
  4. Escrever gdb exec core em que exec é o nome do executável
  5. Dentro do debugger começar por escrever where para ver o que aconteceu e usar o comando up para navegar na stack e o comando p para ver o valor das variáveis

Exemplo

O ficheiro:

#include 

int g(char *s, int n) {
        int j;

        for(j = 0; j < n; j++)
                s[j] += 'A' - 'a';
        return 0;
}

int f(char *s) {
        return g(s, 100);
}

int main() {
        char *buf = NULL;

        f(buf);
        printf("%s\n", buf);
}

Compilar e correr

rui@omega:/tmp/l$ gcc -ggdb c.c
rui@omega:/tmp/l$ ./a.out
Segmentation fault (core dumped)
rui@omega:/tmp/l$ gdb a.out core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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 "i686-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /tmp/l/a.out...done.
[New LWP 26633]

Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x080483ef in g (s=0x0, n=100) at c.c:7
7                       s[j] += 'A' - 'a';
(gdb) where
#0  0x080483ef in g (s=0x0, n=100) at c.c:7
#1  0x08048423 in f (s=0x0) at c.c:12
#2  0x08048442 in main () at c.c:18
(gdb)

Em alternativa:

rui@omega:/tmp/l$ gdb a.out
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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 "i686-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /tmp/l/a.out...done.
(gdb) run
Starting program: /tmp/l/a.out

Program received signal SIGSEGV, Segmentation fault.
0x080483ef in g (s=0x0, n=100) at c.c:7
7                       s[j] += 'A' - 'a';
(gdb) where
#0  0x080483ef in g (s=0x0, n=100) at c.c:7
#1  0x08048423 in f (s=0x0) at c.c:12
#2  0x08048442 in main () at c.c:18
(gdb) where
#0  0x080483ef in g (s=0x0, n=100) at c.c:7
#1  0x08048423 in f (s=0x0) at c.c:12
#2  0x08048442 in main () at c.c:18
(gdb) p s
$1 = 0x0
(gdb) up
#1  0x08048423 in f (s=0x0) at c.c:12
12              return g(s, 100);
(gdb) up
#2  0x08048442 in main () at c.c:18
18              f(buf);
(gdb) p buf
$2 = 0x0
(gdb)

Tutoriais do GDB