O que significa a mensagem de registo de chamadas GDB “0x0000000000000000 em ?? ()" significar?

StackOverflow https://stackoverflow.com/questions/121326

Pergunta

O que significa quando se dá um backtrace com o seguinte resultado?

#0  0x00000008009c991c in pthread_testcancel () from /lib/libpthread.so.2
#1  0x00000008009b8120 in sigaction () from /lib/libpthread.so.2
#2  0x00000008009c211a in pthread_mutexattr_init () from /lib/libpthread.so.2
#3  0x0000000000000000 in ?? ()

O programa deixou de funcionar com um sinal padrão 11, falha de segmentação. Meu aplicativo é um multi-threaded programa FastCGI C ++ em execução no FreeBSD 6.3, utilizando pthread como a biblioteca threading.

Tem sido compilado com -g e todas as tabelas de símbolos para a minha fonte são carregados, de acordo com fontes de informação.

Como é evidente, nenhum dos meu código real aparece no rastreamento, mas sim o erro parece se originar de bibliotecas pthread padrão. Em particular, o que é ?? () ????

Editar : finalmente rastreado a queda para baixo para um acesso padrão de memória inválido no meu código principal. não explica por que o rastreamento de pilha foi corrompido, mas isso é uma questão para outro dia:)

Foi útil?

Solução

gdb não foi capaz de extrair o endereço de retorno adequada de pthread_mutexattr_init; ele tem um endereço de 0. O "??" é o resultado de olhar para cima endereço 0 na tabela de símbolos. Ele não consegue encontrar um nome simbólico, para que ele imprime um padrão "??"

Infelizmente direito improviso Eu não sei por que ele não poderia extrair o endereço de retorno correto.

Outras dicas

Algo que causou a biblioteca de threading a falhar. Desde a própria biblioteca de threading não é compilado com símbolos de depuração (-g), ele não pode exibir o arquivo de código-fonte ou número de linha o acidente aconteceu por diante. Além disso, uma vez que é threads, a pilha de chamadas não aponta de volta para o seu arquivo. Infelizmente, este será um bug difícil de rastrear, você vai precisar para percorrer seu código e tentar diminuir quando exatamente o acidente acontece.

Certifique-se de compilar com símbolos de depuração. (Para gcc Eu acho que é a opção -g). Então você deve ser capaz de obter informações mais interessantes fora do GDB. Não se esqueça de desligá-lo quando você compilar a versão de produção.

Eu poderia estar faltando alguma coisa, mas não é esse indicativo de alguém usando NULL como um ponteiro de função?

#include <stdio.h>

typedef int (*funcptr)(void);

int
func_caller(funcptr f)
{
    return (*f)();
}

int
main()
{
    return func_caller(NULL);
}

Isso produz o mesmo estilo de um backtrace se você executá-lo no gdb:

rivendell$ gcc -g -O0 foo.c -o foo
rivendell$ gdb --quiet foo
Reading symbols for shared libraries .. done
(gdb) r
Starting program: ...
Reading symbols for shared libraries . done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00000000 in ?? ()
(gdb) bt
#0    0x00000000 in ?? ()
#1    0x00001f9d in func_caller (f=0) at foo.c:8
#2    0x00001fb1 in main () at foo.c:14

Este é um acidente muito estranho embora ... pthread_mutexattr_init raramente faz nada mais do que alocar uma estrutura de dados e memset-lo. Eu olhar para algo mais acontecendo. Existe a possibilidade de bibliotecas de threading incompatíveis ou algo assim. Meu conhecimento BSD é um pouco datados, mas costumava haver questões em torno desta.

Talvez o erro que causou o acidente quebrou a pilha (partes sobrescritos da pilha)? Nesse caso, o registo de chamadas podem ser inúteis; não sabia o que fazer nesse caso ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top