Pergunta

Estou escrevendo uma biblioteca de programação baseada em eventos para uso no BeagleBone Black e encontrei um erro estranho.

Quando compilo exatamente o mesmo código com os mesmos sinalizadores, recebo os seguintes erros no processador baseado em ARM, mas não quando executo o código compilado para meu computador x86.

$ ./missionControl
pure virtual method called
pure virtual method called
pure virtual method called
terminate called recursively
terminate called recursively
Aborted

Quando compilo e executo no meu laptop, o programa é executado corretamente.

Este é o comando que estou usando para compilar (estou usando um Makefile, mas ambos os métodos de compilação exibem exatamente o mesmo comportamento):

g++ -std=gnu++11 -pthread -O3 -D_GLIBCXX_USE_NANOSLEEP -o missionControl `find . -name *.cpp`

Não importa se eu compilei com o Ubuntu arm-linux-gnueabi-g++ ou compatível com ARM g++ no BeagleBone real, ainda recebo erros no ARM.

Minha pergunta é esta:O que poderia estar causando esse erro e o que posso fazer para tentar encontrar a fonte?Por que isso aconteceria em uma arquitetura de processador, mas não em outra, para a mesma versão do G++?

Obrigado!

Aqui está um backtrace do GDB do processador ARM:

#0  0xb6d4adf8 in raise () from /lib/libc.so.6
#1  0xb6d4e870 in abort () from /lib/libc.so.6
#2  0xb6f50ab4 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#3  0xb6f4ea4c in ?? () from /usr/lib/libstdc++.so.6
#4  0xb6f4ea4c in ?? () from /usr/lib/libstdc++.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Foi útil?

Solução

O problema acabou sendo devido a um bug na versão ARM do libstdc++ que roda no BeagleBone.Um pequeno programa de brinquedo que não possui nenhuma função virtual causa o mesmo erro ("função virtual pura chamada") quando std::thread é criado.

Vou tentar compilar uma versão customizada do gcc/libstdc++ 4.8 no próprio BeagleBone - mesmo que demore muito.

Outras dicas

O método virtual puro chamado O erro ocorre quando você tenta usar o despacho dinâmico para chamar uma função que é puramente virtual em uma base antes que o tipo derivado que a implementa tenha sido construído ou depois de já ter sido destruído.

A causa mais comum para isso é se a classe base tenta chamar uma função virtual que é pura nesse nível por meio do construtor ou destruidor.Fora isso, como foi apontado em alguns comentários, se você tentar acessar um objeto morto, também poderá se deparar com o mesmo problema.

Basta anexar um depurador ao programa e ver qual função virtual é chamada e de onde.

Ver: https://groups.google.com/forum/#!topic/automatak-dnp3/Jisp_zGhd5I

E: Por que este exemplo simples de threading do c++ 11 falha quando compilado com o clang 3.2?

Agora, não tenho ideia de por que isso funciona, mas pelo menos para mim funciona.Adicione as seguintes quatro definições de pré-processador à linha de comando do compilador:

__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8

Não experimentei para ver se todos eles são necessários ou se você pode ou não usar apenas alguns.Mas isso resolveu o problema para mim.Obrigado a todos aqueles que escreveram as respostas acima e ao meu colega por me superar no Google :)

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