Я пытаюсь кросс-компилировать большую библиотеку (TensorFlow), используя gcc в Ubuntu. Я установил набор инструментов g ++ - arm-linux-gnueabihf и смог успешно собрать мой бинарный файл. Процесс, который я использую для сборки, описан здесь: https://github.com/petewarden4prs/tensorflow/tree/master/tensorflow/contrib/makefile#raspberry-pi
Первоначально я обнаружил ошибку, что pthreading был отключен («Включить многопоточность для использования std :: thread: операция не разрешена»), когда я попытался запустить полученный исполняемый файл на моем Pi 3. Я перекомпилировал с -pthread включенным в качестве опции компиляции, и теперь программа вылетает на первый взгляд случайным образом с ошибками сегментации. Запуская его в gdb, они часто связаны с вызовом free () с плохими указателями, а стеки вызовов кажутся испорченными, поэтому я предполагаю, что происходит некоторое несовпадение памяти.
У кого-нибудь есть предложения о том, что я могу попытаться отследить, что здесь происходит не так?
Вот еще некоторые подробности из моего Пи:
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
Вот пример типичного сеанса в 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?)
источник
Ответы:
Самый простой способ кросс-компиляции в двоичном формате - это установка набора инструментов, используемого разработчиками Raspbian. Это можно найти здесь . Важно использовать этот набор инструментов, если вы хотите собрать ядро и драйверы, поскольку объекты ядра требуют идеальной совместимости с ABI, но безупречная совместимость не повредит, если вы также создаете двоичные файлы пользовательского пространства.
Согласно документации , этот набор инструментов совместим с текущей Ubuntu, как 32-битной, так и 64-битной.
источник
Я получал
pure virtual method called
исключение при кросс-компиляции. Ответ @ JeremyBarnes не совсем для меня. Вместо этого я использовал:Объяснение :
Как указал @JeremyBarnes, чтобы обеспечить совместимость ABI вашего приложения с установленным stdc ++, они должны быть скомпилированы с одинаковыми
SYNC
флагами.На Распбиане:
Без исправления
dockcross/linux-armv6
иdockcross/linux-armv7
:С исправлением
dockcross/linux-armv6
иdockcross/linux-armv7
:источник
Кстати, это можно исправить, добавив
-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
флаги компилятора.Почему? В /usr/include/c++/4. average8,9 innovative/bits/concurrency.h политика блокировки по умолчанию зависит от следующих определений:
ABI общего указателя зависит от того, как эти флаги определены, поскольку он наследуется от базового класса, который использует аргумент шаблона по умолчанию для политики блокировки. Следовательно, изменение этих флагов изменяет компоновку (поскольку она меняет компоновку базового класса) объектов std :: shared_ptr <...> в стандартной библиотеке C ++.
В компиляторе, который идет с Pi, с помощью которого был построен Raspbian, они установлены следующим образом:
Это разумно для Pi 1, но это большой позор для Pi 3, который вполне может использовать атомные общие указатели.
На Ubuntu они настроены так:
Приведенные выше флаги командной строки сбрасывают их до значений по умолчанию на Pi.
Кросс-компиляция того стоит; Tensorflow уже медленно строится на мощном сервере; должно занять невероятно много времени, чтобы построить на Пи!
источник