Estou tentando compilar uma biblioteca grande (TensorFlow) usando o gcc no Ubuntu. Instalei a cadeia de ferramentas g ++ - arm-linux-gnueabihf e consegui construir com êxito o meu binário. O processo que estou usando para criar está documentado aqui: https://github.com/petewarden4prs/tensorflow/tree/master/tensorflow/contrib/makefile#raspberry-pi
Inicialmente, encontrei um erro que o pthreading estava desativado ("Ativar o multithreading para usar std :: thread: operação não permitida") quando tentei executar o executável resultante no meu Pi 3. Recompilei com -pthread ativado como uma opção de compilação e agora o programa trava aparentemente aleatoriamente com falhas de segmentação. Ao executá-lo em gdb, eles geralmente parecem relacionados ao free () ser chamado com ponteiros ruins e as pilhas de chamadas parecem corrompidas, então estou assumindo que há alguma incompatibilidade de memória acontecendo.
Alguém tem sugestões sobre coisas que eu posso tentar rastrear aqui?
Aqui estão mais alguns detalhes do meu Pi:
pi@raspberrypi ~ $ uname -a
Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux
pi@raspberrypi ~ $ file benchmark
benchmark: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x5043384f5d0003f8074b07dfdd38cdc20315143f, not stripped
Aqui está um exemplo de uma sessão típica no gdb:
[New Thread 0x76cf5450 (LWP 6011)]
*** glibc detected *** /home/pi/benchmark: free(): invalid pointer: 0x018e2e89 ***
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x76cf5450 (LWP 6011)]
0x76f98e40 in std::string::c_str() const () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
(gdb) thread apply all bt
Thread 2 (Thread 0x76cf5450 (LWP 6011)):
#0 0x76f98e40 in std::string::c_str() const () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#1 0x00bad996 in tensorflow::thread::ThreadPool::Impl::WorkerLoop() ()
#2 0x00bad5de in tensorflow::thread::ThreadPool::Impl::Impl(tensorflow::Env*, tensorflow::ThreadOptions const&, std::string const&, int)::{lambda()#1}::operator()() const ()
#3 0x00badec2 in std::_Function_handler<void (), tensorflow::thread::ThreadPool::Impl::Impl(tensorflow::Env*, tensorflow::ThreadOptions const&, std::string const&, int)::{lambda()#1}>::_M_invoke(std::_Any_data const&) ()
#4 0x0029aaf4 in std::function<void ()>::operator()() const ()
#5 0x00b53e1e in _ZNSt12_Bind_simpleIFSt8functionIFvvEEvEE9_M_invokeIJEEEvSt12_Index_tupleIJXspT_EEE ()
#6 0x00b53d90 in std::_Bind_simple<std::function<void ()> ()>::operator()() ()
#7 0x00b53d4a in std::thread::_Impl<std::_Bind_simple<std::function<void ()> ()> >::_M_run() ()
#8 0x76f91848 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#9 0x76f91848 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Thread 1 (Thread 0x76ff6000 (LWP 6010)):
#0 0x76dfc61c in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
#1 0x76fff048 in ?? () from /lib/ld-linux-armhf.so.3
Cannot access memory at address 0x158
#2 0x76fff048 in ?? () from /lib/ld-linux-armhf.so.3
Cannot access memory at address 0x158
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
fonte
Respostas:
A maneira mais fácil de uma compilação cruzada compatível com binário é instalar o conjunto de ferramentas usado pelos desenvolvedores do Raspbian. Pode ser encontrado aqui . É essencial usar essa cadeia de ferramentas se você deseja construir o kernel e os drivers, pois os objetos do kernel exigem compatibilidade ABI perfeita, mas ter compatibilidade perfeita não será prejudicial se você também estiver construindo binários do espaço do usuário.
De acordo com a documentação , essa cadeia de ferramentas é compatível com o atual Ubuntu, de 32 e 64 bits.
fonte
Eu estava recebendo uma
pure virtual method called
exceção ao fazer a compilação cruzada. A resposta de @ JeremyBarnes não funcionou muito bem para mim. Em vez disso, usei:Explicação :
Como o @JeremyBarnes apontou, para garantir a compatibilidade ABI do seu aplicativo com o stdc ++ instalado, ambos precisam ser compilados com os mesmos
SYNC
sinalizadores.Em Raspbian:
Sem a correção
dockcross/linux-armv6
edockcross/linux-armv7
:Com a correção ativada
dockcross/linux-armv6
edockcross/linux-armv7
:fonte
FWIW, isso pode ser corrigido adicionando
-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
aos sinalizadores do compilador.Por quê? Em /usr/include/c++/4.{8,9}/bits/concurrency.h, a política de bloqueio padrão depende dos seguintes parâmetros:
A ABI de um ponteiro compartilhado depende de como esses sinalizadores são definidos, pois herda de uma classe base que usa um argumento de modelo padrão para a política de bloqueio. Portanto, alterar esses sinalizadores altera o layout (porque altera o layout da classe base) dos objetos std :: shared_ptr <...> na biblioteca C ++ padrão.
No compilador que acompanha o Pi, com o qual o Raspbian foi criado, eles são definidos da seguinte maneira:
Isso é sensato para o Pi 1, mas é uma grande vergonha para o Pi 3, que pode usar alegremente ponteiros compartilhados atômicos.
No Ubuntu, eles são configurados assim:
Os sinalizadores da linha de comando acima os redefinem como estão por padrão no Pi.
A compilação cruzada vale a pena; O Tensorflow já é lento para construir em um servidor robusto; deve levar um tempo incrivelmente longo para desenvolver o Pi!
fonte