A debugger plays a vital role in any software development system. Nobody can write a bug-free code all at once. During the course of development, bugs are being raised and needs to be solved for further enhancement. A development system is incomplete without a debugger. Considering the open source developers community, GNU Debugger is their best choice. It is also used for commercial software development on UNIX type platforms.

GNU Debugger, também conhecido como gdb, nos permite navegar pelo 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 identificar falhas no código-fonte.
- Iniciar o programa, especificando argumentos que podem afetar o comportamento geral.
- Parar o programa em condições especificadas.
- Examinar a falha ou quando o programa foi parado.
- Alterar o código e experimentar com o código modificado instantaneamente.
Podemos usar o gdb para depurar programas escritos em C e C++ sem muito esforço. Até o momento, o suporte para outras linguagens de programação como D, Modula-2 e Fortran é parcial.
Começando com o GNU Debugger ou GDB
GDB é invocado usando o comando gdb. Ao emitir o comando gdb, ele exibe algumas informações sobre a plataforma e o direciona para o prompt do (gdb) conforme mostrado abaixo.
[root@fedora20 ~]# gdb
Saída de exemplo
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 para listar as diferentes classes de comandos disponíveis dentro do gdb. Digite help seguido por um nome de classe para 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 forem inequívocas. Por exemplo, você pode digitar n em vez de digitar next ou c para continue e assim por diante.
Comandos GDB Mais Comuns
Os comandos gdb mais comuns estão listados na tabela a seguir. Esses comandos devem ser usados a partir do prompt de comando do gdb (gdb).
Command
|
Description
|
run
|
Start a program execution
|
quit
|
Quit gdb
|
print expr
|
Print expression where expr may be a variable name too
|
next
|
Go to next line
|
step
|
Step into next line
|
continue
|
Continue from the current line till the end of program or next break point
|
Observe a diferença entre os dois comandos step e next. O comando next não entra em uma função se a próxima linha for uma chamada de função. Enquanto o comando step pode entrar na função e ver o que acontece lá dentro.
A sample session with 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 o gcc da seguinte forma.
$ gcc -g sum.c -o sum
O arquivo de saída sum pode ser anexado ao gdb de duas maneiras diferentes:
1. Especificando o arquivo de saída como argumento para o 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. Então, primeiro list irá exibir as primeiras 10 linhas e o próximo list 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 pontos de interrupção no código-fonte para depuração, certo? Esses pontos de interrupção podem ser especificados para funções ou em linhas especificadas.
(gdb) b main
Nota: Eu usei a abreviação b para break.
Depois de definir um ponto de interrupção na função principal, ao executar novamente o programa irá parar na linha 11. A mesma coisa pode ser feita se o número da linha for conhecido antes.
(gdb) b sum.c:11
Agora, avance pelas linhas de código usando o comando próximo ou n. É importante notar que o comando próximo não entra no código da função, a menos que um ponto de interrupção seja definido na função. Vamos experimentar o comando imprimir agora. Defina um ponto de interrupção na função soma como 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 em execução exigir parâmetros da linha de comando, forneça o mesmo juntamente com o comando executar.
(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
GDB também é capaz de modificar variáveis durante a execução do programa. Vamos tentar isso. Como mencionado acima, defina um 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 mudamos o resultado final para z = 4 na função principal. Dessa 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 está ligado. Para desativar os pontos de interrupção, especifique o número do ponto de interrupção junto com o comando desativar. Para ativar posteriormente, use o comando ativar.
(gdb) disable 1 (gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep n 0x00000000004005c2 in main at sum.c:11
Também pode excluir os pontos de interrupção com o comando delete.
Depurar Processos em Execução
Inúmeros processos estão em execução em segundo plano em um sistema GNU/Linux. Para depurar um processo em execução, primeiro precisamos encontrar o id do processo específico. O comando pidof fornece o pid de um processo.
$ pidof <process_name>
Agora precisamos anexar esse pid ao gdb. Existem 2 maneiras.
1. Especificando o pid juntamente com o gdb.
$ gdb -p <pid>
2. Usando o comando attach do gdb.
(gdb) attach <pid>
Por enquanto é isso. Estes são apenas conceitos básicos do gdb para começar bem na depuração de código fonte e vai além do que foi explicado acima. Por exemplo, podemos depurar usando informações da pilha, variáveis de ambiente e muito mais. Experimente brincar com todas essas coisas…
Source:
https://www.tecmint.com/debug-source-code-in-linux-using-gdb/