1
Obrigado

Algumas palavras de agradecimento nunca são demais.

Linguagem C: C/C++ Falha de segmentação

Você está desenvolvendo uma aplicação no Linux em C/C++. Tudo corre bem, ele está compilando, então, você executa a aplicação para testá-la e recebe mensagens de falha. Veja o que fazer se isso acontecer.



Você recebeu as mensagens
Falha de segmentação
ou
Segmentation fault
?

Ou, ainda, quando há um erro em uma linguagem de alto nível (perl, python, java, etc.), a mensagem de desbloqueio é mais detalhada, explicando que tipo de exceção ocorreu, a que linha do programa a falha corresponde, etc.

Por outro, em uma linguagem compilada (ou seja, transformada em linguagem facilmente compreensível por seu processador), como C ou C++, seu programa não está sob o controle de nenhum intérprete ou máquina virtual. Assim sendo, ninguém pode monitorar e analisar seus erros.

Felizmente, existem programas chamados desbloqueadores facilitar sua vida.

Saiba que um sistema operacional moderno (Windows NT/2000/XP/; Linux) aloca uma parte da memória para cada aplicação. Se um aplicativo tenta entrar diretamente em uma área de memória que não lhe pertence ou em uma área de memória incorreta, o sistema operacional vai interromper o aplicativo em curso e gerar um erro (Linux: Falha de segmentação).

Em C

Consideremos, por exemplo, um programa em C bem simples, que trava voluntariamente e gera uma falha de segmentação:

void execute_falha_segmentação() 
{
int *ponteiro_perigoso=(int *) 100;
int test=* ponteiro_ perigoso;
}

int main(int argc, char ** argv)
{
execute_falha_segmentação ();
return 0;
}


Na função execute_falha_segmentação, o ponteiro_perigoso aponta para o endereço 100 na memória.
Este é um endereço que não pode pertencer a uma aplicação normal.

Quando o ponteiro_perigoso tentará ler o que está no endereço de memória 100, para destacar o valor situado neste endereço na variável teste, o programa vai falhar.

E você receberá a mensagem "Falha de segmentação".

Para desbloquear este programa, vamos começar por compilá-lo carregando seus símbolos de desbloqueio. Isto permite, principalmente, carregar os nomes de funções e variáveis utilizadas no programa, depois de compilado; assim, o desbloqueador podeá rastrear o erro indicando os nomes das funções em causa, ao invés de dar apenas seu endereço.

Falamos da opção-g

Vamos compilar:
gcc -g test.c -o test

E vamos executar o programa no desbloqueador:
gdb ./test

Você verá um prompt de comando que começa por:
(gdb)

Digite o comando run

Vejamos o que acontece:

(gdb) run 
Starting program: ~/test

Program received signal SIGSEGV, Segmentation fault.
0x08048334 in executa_falha_segmentação () at test.c:4
4 int test=*ponteiro_perigoso;


O que pedir a mais: o desbloqueador mostra a linha em seu arquivo de origem que está
causando o erro, assim como a função em questão e o conteúdo da linha:

É um erro na função executa_falha_segmentação no arquivo fonte test.c na linha 4 cujo conteúdo é

int test=*ponteiro_perigoso;


Se você quiser saber a função executada desde o início do programa até a ocorrência do erro:

Digite o comando bt:

(gdb) bt 
#0 0x08048334 in executa_falha_segmentação() at test.c:4
#1 0x0804834e in main () at test.c:9

E você obtém outra vez o que você precisa!

Em C++

Para continuar com esse mesmo problema: as falhas de segmentação, não há muito a acrescentar para o C++, exceto que se trata de usar o comando g++ com a opção -g da mesma maneira que com o gcc.

O relatório do gdb será o mesmo, mas com os detalhes das classes em questão.

Exemplo:


//Arquivo teste.cpp
class Test{
public:
int a;
Test(){};
~Test(){};
int incremente_a(){ a++; };
};

int main()
{
Test *t;
t=(Test *)100;
t->incremente_a();
return 0;
}


Compilamos assim:
g++ -g test.cpp -o test


Executamos o desbloqueador:
gdb ./test

Depois, digite os mesmos comandos que antes e todos os detalhes aparecerão:
(gdb) run 
Starting program: ~/test

Program received signal SIGSEGV, Segmentation fault.
0x080483fc in Test::incremente_a (this=0x64) at test.cpp:7
7 int incremente_a(){ a++; };
(gdb) bt
#0 0x080483fc in Test::incremente_a (this=0x64) at test.cpp:7
#1 0x080483e7 in main () at test.cpp:14


Foto: © Rich Tervet - Unsplash

Veja também

Este documento, intitulado 'Linguagem C - C/C++ Falha de segmentação ', está disponível sob a licença Creative Commons. Você pode copiar e/ou modificar o conteúdo desta página com base nas condições estipuladas pela licença. Não se esqueça de creditar o CCM (br.ccm.net) ao utilizar este artigo.

0 Comentário