Saya mencoba mengkompilasi silang pustaka besar (TensorFlow) menggunakan gcc di Ubuntu. Saya telah menginstal g ++ - arm-linux-gnueabihf toolchain, dan berhasil membangun biner saya. Proses yang saya gunakan untuk membangun didokumentasikan di sini: https://github.com/petewarden4prs/tensorflow/tree/master/tensorflow/contrib/makefile#raspberry-pi
Awalnya saya menemukan kesalahan bahwa pthreading dinonaktifkan ("Aktifkan multithreading untuk menggunakan std :: thread: Operasi tidak diizinkan") ketika saya mencoba menjalankan executable yang dihasilkan pada Pi 3. Saya mengkompilasi ulang dengan -pthread diaktifkan sebagai opsi kompilasi, dan sekarang program crash secara acak dengan kesalahan segmentasi. Menjalankannya di gdb, mereka sering tampak berhubungan dengan free () dipanggil dengan pointer buruk, dan tumpukan panggilan tampaknya rusak, jadi saya berasumsi ada beberapa ketidakcocokan memori yang terjadi.
Adakah yang punya saran tentang hal-hal yang bisa saya coba lacak apa yang salah di sini?
Berikut ini beberapa detail dari Pi saya:
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
Berikut adalah contoh sesi khas di 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?)
sumber
Jawaban:
Cara termudah untuk kompilasi silang yang kompatibel dengan biner adalah dengan menginstal toolchain yang digunakan oleh pengembang Raspbian. Itu dapat ditemukan di sini . Sangat penting untuk menggunakan rantai alat ini jika Anda ingin membangun kernel dan driver, karena objek kernel membutuhkan kompatibilitas ABI yang sempurna, tetapi memiliki kompatibilitas yang sempurna tidak akan merugikan jika Anda juga membangun biner userspace.
Menurut dokumentasi , rantai alat ini kompatibel dengan Ubuntu saat ini, baik 32-bit dan 64-bit.
sumber
Saya mendapat
pure virtual method called
pengecualian saat kompilasi silang. @ JeremyBarnes jawaban tidak cukup untuk saya. Sebaliknya saya menggunakan:Penjelasan :
Seperti yang ditunjukkan oleh @JeremyBarnes, untuk memastikan kompatibilitas ABI aplikasi Anda dengan stdc yang diinstal ++, keduanya perlu dikompilasi dengan
SYNC
flag yang sama .Tentang Raspbian:
Tanpa perbaikan
dockcross/linux-armv6
dandockcross/linux-armv7
:Dengan perbaikan
dockcross/linux-armv6
dandockcross/linux-armv7
:sumber
FWIW, ini bisa diperbaiki dengan menambahkan
-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
ke flag compiler.Mengapa? Di /usr/include/c++/4.{8,9}/bits/concurrency.h, kebijakan kunci default bergantung pada definisi ini:
ABI dari sebuah pointer bersama tergantung pada bagaimana flag-flag ini didefinisikan, karena itu mewarisi dari kelas dasar yang menggunakan argumen templat default untuk kebijakan penguncian. Oleh karena itu, mengubah flag-flag ini mengubah tata letak (karena itu mengubah tata letak kelas dasar) dari std :: shared_ptr <...> objek dalam pustaka C ++ standar.
Dalam kompiler yang datang dengan Pi, dengan Raspbian yang dibangun, mereka ditetapkan sebagai berikut:
Ini masuk akal untuk Pi 1, tetapi sangat memalukan untuk Pi 3 yang bisa dengan senang hati menggunakan pointer atom bersama.
Di Ubuntu, mereka diatur seperti ini:
Bendera baris perintah di atas mengatur ulang mereka menjadi seperti semula pada Pi.
Kompilasi silang sepadan; Tensorflow sudah lambat dibangun di server yang gemuk; harus memakan waktu yang sangat lama untuk membangun Pi!
sumber