Universidade de Indiana Universidade de Indiana, Indiana University

esta página:

  • Descrição
  • Exemplos de comum segfaults
  • Encontrar fora dos limites da matriz de referências
  • Verifique shell limites
  • Use depuradores para diagnosticar segfaults

Descrição

Uma falha de segmentação (aka segfault) é uma condição comum que faz com que a falha de programas; eles são frequentemente associados com um arquivo chamado core. Segfaults são causados por um programa tentando ler ou escrever um local de memória ilegal.

a memória de Programa é dividido em diferentes segmentos: um segmento de texto de instruções de programa, um segmento de dados para variáveis e matrizes definidas em tempo de compilação, um segmento de pilha temporária (ou automática) variáveis definidas no sub-rotinas e funções, e um segmento de pilha para as variáveis alocadas durante o tempo de execução por funções, tais como malloc (C) e allocate (Fortran). Para mais, Veja sobre os segmentos do programa.

uma segfault ocorre quando uma referência a uma variável cai fora do segmento onde essa variável reside, ou quando uma escrita é tentada para um local que está em um segmento apenas de leitura. Na prática, segfaults são quase sempre devido ao tentar ler ou escrever um inexistente elemento de matriz, não corretamente a definição de um ponteiro antes de usá-lo, ou (em programas C) acidentalmente, usando o valor de uma variável como um endereço (consulte o scanf exemplo abaixo).

Exemplos de comum segfaults

  • Por exemplo, chamar memset() como mostrado abaixo seria fazer com que um programa segfault:
    memset((char *)0x0, 1, 100);
  • três casos A seguir ilustram os tipos mais comuns relacionadas com a matriz segfaults:

    Caso

    /* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */ int foo; for (int i = 0; i <= 1000 ; i++) foo = i;

    Caso B

    /* Illegal memory access if value of n is not in the range 0, 1, ... 999 */ int n; int foo; for (int i = 0; i < n ; i++) foo = i;

    C

    /* Illegal memory access because no memory is allocated for foo2 */ float *foo, *foo2; foo = (float*)malloc(1000); foo2 = 1.0;

    • No caso A, matriz foo está definido para index = 0,1, 2, ... 999. No entanto, na última iteração dofor loop, o programa tenta acessar foo. Isto resultará em uma segfault se essa localização de memória estiver fora do segmento de memória onde foo reside. Mesmo que não cause uma segfault, ainda é um bug.
    • No caso B, inteiro n pode ser qualquer valor aleatório. Como no caso A, se não estiver na gama 0, 1, ... 999, pode causar uma segfault. Quer seja ou não, é certamente um bug.
    • No caso C, alocação de memória para variável foo2 foi negligenciada, então foo2 irá apontar para uma localização Aleatória na memória. Acessando foo2 provavelmente resultará em uma segfault.
  • outro erro de programação comum que leva a segfaults é a supervisão no uso de ponteiros. Por exemplo, a função C scanf() espera o endereço de uma variável como o segundo parâmetro; portanto, o seguinte provavelmente fará com que o programa falha com um segfault:
    int foo = 0; scanf("%d", foo); /* Note missing & sign ; correct usage would have been &foo */

    A variável foo pode ser definido na localização de memória 1000, mas acima de chamada de função iria tentar ler dados inteiro na memória local 0 de acordo com a definição de foo.

  • uma segfault ocorrerá quando UM programa tenta operar em um local de memória de uma forma que não é permitido (por exemplo, tentativas de escrever um local somente para leitura resultariam em uma segfault).
  • Segfaults também podem ocorrer quando o seu programa fica sem espaço de pilha. Este pode não ser um bug no seu programa, mas pode ser devido ao seu shell definir o limite de tamanho da pilha muito pequeno.

encontre referências de array fora dos limites

a maioria dos compiladores Fortran tem uma opção que irá inserir código para fazer a verificação de limites em todas as referências de array durante a execução. Se um acesso cair fora do intervalo de índice definido para um array, o programa irá parar e dizer-lhe onde isso ocorre. Para a maioria dos compiladores Fortran, a opção é -C, ou -check seguido por uma palavra-chave. Veja o Guia de usuário do seu compilador para obter a opção exata. Use a verificação de limites apenas quando depurar, uma vez que irá atrasar o seu programa. Alguns compiladores C também têm uma opção de verificação de limites.

verifique os limites da linha de comandos

como indicado no último exemplo acima, alguns problemas de segfault não são devidos a erros no seu programa, mas são causados pelo facto de os limites de memória do sistema estarem muito baixos. Normalmente é o limite no tamanho da pilha que causa este tipo de problema. Para verificar os limites de memória, use o ulimit comando bash ou ksh, ou limit comando csh ou tcsh. Tente ajustar o stacksize mais alto, e em seguida, Executar novamente o seu programa para ver se a segfault vai embora.

Use depuradores para diagnosticar segfaults

Se você não conseguir encontrar o problema de outra forma, você pode tentar um depurador. Por exemplo, você pode usar o GNU é bem conhecido depurador GDB para visualizar o backtrace de uma core arquivo despejado por seu programa, sempre que programas segfault, eles costumam despejar o conteúdo (seção a) memória no momento da falha em um core arquivo. Inicie o seu depurador com o comando gdb core, e depois use o comando backtrace para ver onde estava o programa quando ele estoirou. Este simples truque vai permitir que você se concentre nessa parte do Código.

If using backtrace on the coreg file doesn’t find the problem, you might have to run the program under debugger control, and then step through the code one function, or one source code line, at a time. Para fazer isso, você precisará compilar seu código SEM otimização, e com a opção -g, então informações sobre linhas de código fonte serão incorporadas no arquivo executável. Para mais, veja exemplo passo a passo para usar o GDB dentro do Emacs para depurar um programa em C orC++.

documentos Relacionados

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *