Mudanças entre as edições de "Guia basico GDB"
Linha 263: | Linha 263: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | === Executando até um ponto específico === | |
+ | Uma vez no passo-a-passo, pode-se usar o comando ''advance'' para avançar até uma certa linha do código, ou até uma determinada função. Quer dizer, a execução é feita cotinuamente (sem passo-a-passo) até chegar ao ponto do programa desejado. | ||
+ | |||
+ | <syntaxhighlight lang=bash> | ||
(gdb) run | (gdb) run | ||
+ | Starting program: /home/aluno/exemplo1 | ||
+ | |||
+ | Breakpoint 1, main () at exemplo1.c:13 | ||
+ | 13 int main() { | ||
+ | (gdb) advance 17 | ||
+ | main () at exemplo1.c:17 | ||
+ | 17 fgets(nome, 32, stdin); | ||
+ | (gdb) next | ||
+ | Digite seu nome: maneca | ||
+ | 18 nome[strlen(nome)-1] = 0; | ||
+ | (gdb) continue | ||
+ | Continuando. | ||
+ | acenam | ||
+ | [Inferior 1 (process 17077) exited normally] | ||
+ | (gdb) | ||
+ | </syntaxhighlight> | ||
+ | ''Avançando até uma certa linha do programa'' | ||
+ | |||
− | + | <syntaxhighlight lang=bash> | |
+ | (gdb) run | ||
+ | Starting program: /home/aluno/exemplo1 | ||
− | (gdb) | + | Breakpoint 1, main () at exemplo1.c:13 |
+ | 13 int main() { | ||
+ | (gdb) advance mostraInvertido | ||
+ | Digite seu nome: maneca | ||
+ | mostraInvertido (texto=0x7fffffffe030 "maneca") at exemplo1.c:7 | ||
+ | 7 for (n=strlen(texto); n > 0; n--) { | ||
+ | (gdb) next | ||
+ | 8 printf("%c", texto[n-1]); | ||
+ | (gdb) continue | ||
+ | Continuando. | ||
+ | acenam | ||
+ | [Inferior 1 (process 17095) exited normally] | ||
+ | (gdb) | ||
+ | </syntaxhighlight> | ||
+ | ''Avançando até uma certa função'' |
Edição das 14h50min de 12 de agosto de 2014
Traduzido de Tutorial of gcc and gdb.
Introdução
'gdb é um depurador (debugger) feito pelo projeto GNU. gdb pode executar passo a passo o seu programa linha por linha e mesmo instrução por instrução. Com ele se consegue também observar o valor de qualquer variável em tempo de execução. Por fim, ele ajuda a identificar o lugar e o motivo que causou um erro de execução do programa.
Uso básico
Todo programa a ser depurado com gdb precisa ser compilado pelo gcc com a opção -g. Isso é demonstrado abaixo com um pequeno programa de exemplo.
- Copie este programa para o arquivo exemplo.c:
#include <stdio.h> #include <string.h> int main() { int n; char nome[32]; printf("Digite seu nome: "); fgets(nome, 32, stdin); nome[strlen(nome)] = 0; for (n=strlen(nome); n >= 0; n--) { printf("%c", nome[n]); } return 0; }
- Compile-o da seguinte forma:
gcc -g -o exemplo exemplo.c
- Use o gdb para depurá-lo:
gdb ./exemplo
- ... o que vai mostrar uma apresentação do gdb na sua tela:
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 <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". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Lendo símbolos de /home/aluno/exemplo...concluído. (gdb)
- ... o que vai mostrar uma apresentação do gdb na sua tela:
- Antes de iniciar a execução do programa, defina ao menos um ponto de parada (breakpoint). O gdb para a execução nesse ponto, a partir do qual se pode executar passo-a-passo. Um ponto de parada pode ser uma função ou uma linha do programa. No exemplo, o ponto de parada foi definido como sendo a função main:
(gdb) break main Ponto de parada 1 at 0x40063c: file exemplo.c, line 4.
- Execute o programa, notando que a execução para no ponto de parada que foi definido:
(gdb) run Starting program: /home/aluno/exemplo Breakpoint 1, main () at exemplo.c:4 4 int main() {
- Para avançar uma linha do programa, use o comando next. Após esse comando é mostrada a próxima linha do programa a ser executada:
(gdb) next 8 printf("Digite seu nome: ");
- Para terminar a depuração, use o comando quit:
(gdb) quit A debugging session is active. Inferior 1 [process 15861] will be killed. Quit anyway? (y or n) Y
Execução de um programa que pede argumentos de linha de comando
Devem-se informar os argumentos do programa em seguida ao comando run. Ex: se o programa exemplo pedisse um argumento:
(gdb) run arg1
... e se pedisse dois argumentos:
(gdb) run arg1 arg2
Passo a passo
A execução passo-a-passo pode ser feita com os comandos next ou step. Com next executa-se uma linha de código, sem entrar em funções que porventura sejam chamadas. Com step executa-se uma linha, porém entrando em funções chamadas. Por exemplo, seja o programa exemplo1.c abaixo:
#include <stdio.h>
#include <string.h>
void mostraInvertido(char * texto) {
int n;
for (n=strlen(texto); n > 0; n--) {
printf("%c", texto[n-1]);
}
puts("");
}
int main() {
char nome[32];
printf("Digite seu nome: ");
fgets(nome, 32, stdin);
nome[strlen(nome)-1] = 0;
mostraInvertido(nome);
return 0;
}
Se a depuração passo-a-passo for realizada com next:
(gdb) break main
Ponto de parada 1 at 0x4006f4: file exemplo1.c, line 13.
(gdb) run
Starting program: /home/aluno/exemplo1
Breakpoint 1, main () at ex1.c:13
13 int main() {
(gdb) next
16 printf("Digite seu nome: ");
(gdb) next
17 fgets(nome, 32, stdin);
(gdb) next
Digite seu nome: maneca
18 nome[strlen(nome)-1] = 0;
(gdb) next
19 mostraInvertido(nome);
(gdb) next
acenam
20 return 0;
(gdb) next
21 }
(gdb) next
0x00007ffff7a3b78d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)
Note o que acontece se for usado step ao executar a linha 19 (mostraInvertido(nome)). O depurador começa a executar dentro da funjção mostraInvertido:
(gdb) run
Starting program: /home/msobral/tmp/ex1
Breakpoint 1, main () at ex1.c:13
13 int main() {
(gdb) next
16 printf("Digite seu nome: ");
(gdb) next
17 fgets(nome, 32, stdin);
(gdb) next
Digite seu nome: maneca
18 nome[strlen(nome)-1] = 0;
(gdb) next
19 mostraInvertido(nome);
(gdb) step
mostraInvertido (texto=0x7fffffffe030 "maneca") at ex1.c:7
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
10 puts("");
(gdb) next
acenam
11 }
(gdb) next
main () at exemplo1.c:20
20 return 0;
(gdb) next
21 }
(gdb) next
0x00007ffff7a3b78d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)
Executando até o o final de uma função
Estando no passo-a-passo, pode-se executar até o final da função corrente com o comando finish. Assim o programa executa direto até chegar o final da função, e logo após retornar volta-se ao passo-a-passo:
(gdb) run
Starting program: /home/aluno/exemplo1
Breakpoint 1, main () at exemplo1.c:13
13 int main() {
(gdb) next
16 printf("Digite seu nome: ");
(gdb) next
17 fgets(nome, 32, stdin);
(gdb) next
Digite seu nome: maneca
18 nome[strlen(nome)-1] = 0;
(gdb) next
19 mostraInvertido(nome);
(gdb) step
mostraInvertido (texto=0x7fffffffe030 "maneca") at ex1.c:7
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) next
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) finish
Run till exit from #0 mostraInvertido (texto=0x7fffffffe030 "maneca")
at ex1.c:8
acenam
main () at exemplo1.c:20
20 return 0;
(gdb) next
21 }
(gdb) next
0x00007ffff7a3b78d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)
Saindo do passo-a-passo
Pode-se sair do passo-a-passo com o comando continue. Com ele o programa volta a executar continuamente, até chegar a um ponto de parada ou terminar.
(gdb) run
Starting program: /home/aluno/exemplo1
Breakpoint 1, main () at exemplo1.c:13
13 int main() {
(gdb) next
16 printf("Digite seu nome: ");
(gdb) next
17 fgets(nome, 32, stdin);
(gdb) continue
Continuando.
Digite seu nome: maneca
acenam
[Inferior 1 (process 17002) exited normally]
(gdb)
Executando até um ponto específico
Uma vez no passo-a-passo, pode-se usar o comando advance para avançar até uma certa linha do código, ou até uma determinada função. Quer dizer, a execução é feita cotinuamente (sem passo-a-passo) até chegar ao ponto do programa desejado.
(gdb) run
Starting program: /home/aluno/exemplo1
Breakpoint 1, main () at exemplo1.c:13
13 int main() {
(gdb) advance 17
main () at exemplo1.c:17
17 fgets(nome, 32, stdin);
(gdb) next
Digite seu nome: maneca
18 nome[strlen(nome)-1] = 0;
(gdb) continue
Continuando.
acenam
[Inferior 1 (process 17077) exited normally]
(gdb)
Avançando até uma certa linha do programa
(gdb) run
Starting program: /home/aluno/exemplo1
Breakpoint 1, main () at exemplo1.c:13
13 int main() {
(gdb) advance mostraInvertido
Digite seu nome: maneca
mostraInvertido (texto=0x7fffffffe030 "maneca") at exemplo1.c:7
7 for (n=strlen(texto); n > 0; n--) {
(gdb) next
8 printf("%c", texto[n-1]);
(gdb) continue
Continuando.
acenam
[Inferior 1 (process 17095) exited normally]
(gdb)
Avançando até uma certa função