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 observar 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 identificar falhas no código fonte.
- Iniciar o programa, especificando argumentos que podem afetar o comportamento geral.
- Parar o programa em condições específicas.
- Examinar o crash ou quando o programa foi interrompido.
- 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. Atualmente, o suporte para outras linguagens de programação como D, Modula-2, Fortran é parcial.
Começando com o GNU Debugger ou GDB
O GDB é invocado usando o comando gdb. Ao emitir o comando gdb, ele exibe algumas informações sobre a plataforma e te 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 list para ver as diferentes classes de comandos disponíveis dentro do gdb. Digite help seguido por um nome de classe para obter uma lista de comandos nessa classe. Digite help all para 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 no 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 dentro da função e ver o que acontece lá.
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 conforme a seguir.
$ gcc -g sum.c -o sum
O arquivo de saída sum pode ser anexado ao gdb por qualquer um dos seguintes 2 modos:
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 10 primeiras linhas e em seguida 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 específicas.
(gdb) b main
Observação: Eu usei a abreviação b para break.
Depois de definir um ponto de interrupção na função principal, reiniciar o programa fará com que ele pare na linha 11. A mesma coisa pode ser feita com efeito se o número da linha for conhecido antes.
(gdb) b sum.c:11
Agora, percorra as linhas de código usando o próximo ou n comando. É 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 sum 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 de linha de comando, forneça os mesmos junto com o executar comando como.
(gdb) run . . .
Os arquivos de biblioteca compartilhados 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 ao longo da execução do programa. Vamos experimentar 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.
Habilitar/Desabilitar 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á habilitado. Para desabilitar os pontos de interrupção, especifique o número do ponto de interrupção junto com o desabilitar comando. Para habilitar depois, use o habilitar comando.
(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 deletar.
Depuração de 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 daquele processo específico. pidof comando fornece o PID de um processo.
$ pidof <process_name>
Agora precisamos anexar este 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>
É isso por enquanto. Estas são apenas noções básicas do gdb para ter um bom começo na depuração do código-fonte e vai muito além das coisas explicadas acima. Por exemplo, podemos depurar usando as 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/