Pesquisa de site

GNU Debugger ou GDB: uma poderosa ferramenta de depuração de código-fonte para programas Linux


Um depurador desempenha um papel vital em qualquer sistema de desenvolvimento de software. Ninguém pode escrever um código livre de bugs de uma só vez. Durante o desenvolvimento, bugs estão sendo levantados e precisam ser resolvidos para melhorias adicionais. Um sistema de desenvolvimento está incompleto sem um depurador. Considerando a comunidade de desenvolvedores de código aberto, o GNU Debugger é a melhor escolha. Também é usado para desenvolvimento de software comercial em plataformas do tipo UNIX.

O GNU Debugger, também conhecido como gdb, nos permite percorrer o código enquanto ele é executado ou o que um programa estava tentando fazer no momento antes de travar. O GDB basicamente nos ajuda a fazer quatro coisas principais para detectar falhas no código-fonte.

  1. Inicie o programa especificando argumentos que podem afetar o comportamento geral.
  2. Pare o programa em condições especificadas.
  3. Examine a falha ou quando o programa foi interrompido.
  4. Altere o código e experimente o código modificado instantaneamente.

Podemos usar o gdb para depurar programas escritos em C e C++ sem muito esforço. A partir de agora o suporte para outras linguagens de programação como D, Modula-2, Fortran é parcial.

Introdução ao GNU Debugger ou GDB

GDB é invocado usando o comando gdb. Ao emitir gdb, ele exibe algumas informações sobre a plataforma e leva você ao prompt (gdb) conforme mostrado abaixo .

[root@fedora20 ~]# gdb
Saída de amostra
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
Copyright (C) 2013 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-redhat-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". 
(gdb)

Digite help list para ver as diferentes classes de comandos disponíveis dentro do gdb. Digite help seguido de um nome de classe para obter uma lista de comandos nessa classe. Digite help all para obter a lista de todos os comandos. Abreviações de nomes de comandos são permitidas se não forem ambíguas. Por exemplo, você pode digitar n em vez de digitar próximo ou c para continuar e assim por diante.

Comandos GDB mais comumente usados

Os comandos gdb comumente usados estão listados na tabela a seguir. Esses comandos devem ser usados no prompt de comando do gdb (gdb).

Command

Descrição

run

Iniciar a execução de um programa

quit

Sair do gdb

print expr

Imprimir expressão onde expr também pode ser um nome de variável

next

Ir para a próxima linha

step

Passar para a próxima linha

continue

Continue da linha atual até o final do programa ou próximo ponto de interrupção

Observe a diferença entre os dois comandos step e next. O comando next não entra na função se a próxima linha for uma chamada de função. Considerando que o comando step pode entrar na função e ver o que acontece lá.

Um exemplo de sessão com GDB

Considere o seguinte código-fonte.


// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

Para depurar o arquivo de saída, precisamos compilá-lo com a opção -g para gcc como segue.

gcc -g sum.c -o sum

O arquivo de saída sum pode ser anexado ao gdb de uma das duas maneiras a seguir:

1. Especificando o arquivo de saída como argumento para gdb.

gdb sum

2. Executando o arquivo de saída dentro do gdb usando o comando file.

gdb
(gdb) file sum

O comando list lista as linhas no arquivo de código-fonte e move o ponteiro. Portanto, a primeira lista exibirá as primeiras 10 linhas e a próxima lista exibirá as próximas 10 e assim por diante.

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

Para iniciar a execução, emita o comando run . Agora o programa é executado normalmente. Mas esquecemos de colocar alguns breakpoints no código fonte para depuração, certo? Esses pontos de interrupção podem ser especificados para funções ou em linhas específicas.

(gdb) b main

Nota: usei uma abreviatura b para quebra.

Depois de definir o ponto de interrupção na função principal, a nova execução do programa irá parar na linha 11. A mesma coisa pode ocorrer se o número da linha for conhecido antes.

(gdb) b sum.c:11

Agora percorra as linhas de código usando o comando next ou n. É importante observar que o comando next não entra no código da função, a menos que um ponto de interrupção seja definido na função. Vamos testar o comando print agora. Defina o ponto de interrupção na soma da função conforme abaixo.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

Se o programa que está sendo executado exigir parâmetros de linha de comando, forneça os mesmos junto com o comando run como.

(gdb) run   . . .

Os arquivos de biblioteca compartilhada associados ao programa em execução atual podem ser listados como.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

Modificando Variáveis

O GDB também é capaz de modificar variáveis durante a execução do programa. Vamos tentar isso. Conforme mencionado acima, defina o ponto de interrupção na linha 16 e execute o programa.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

Agora a=1, b=2 e o resultado deve ser z=3. Mas aqui alteramos o resultado final para z=4 na função principal. Desta forma, a depuração pode ser facilitada usando o gdb.

Ativar/desativar pontos de interrupção

Para obter a lista de todos os pontos de interrupção, digite info breakpoints.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

Aqui há apenas um ponto de interrupção e é To. habilitado desabilitar os pontos de interrupção especifique o número do ponto de interrupção junto com o comando disable. Para habilitar posteriormente use o comando enable.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

Você também pode excluir os pontos de interrupção com o comando delete.

Depurando processos em execução

Vários processos estão sendo executados em segundo plano em um sistema GNU/Linux. Para depurar um processo em execução, primeiro precisamos encontrar o ID do processo desse processo específico. O comando pidof fornece o pid de um processo.

pidof <process_name>

Agora precisamos anexar este pid ao gdb. Existem 2 maneiras.

1. Especificando pid junto com gdb.

gdb -p <pid>

2. Usando o comando attach do gdb.

(gdb) attach <pid>

É tudo por agora. Estes são apenas os princípios básicos do gdb para começar bem a depuração do código-fonte e é muito mais do que o explicado acima. Por exemplo, podemos depurar usando informações de pilha, variáveis de ambiente e muito mais. Tente brincar com todas essas coisas…