Ich versuche, eine große Bibliothek (TensorFlow) mit gcc unter Ubuntu zu kompilieren. Ich habe die Toolkette g ++ - arm-linux-gnueabihf installiert und konnte meine Binärdatei erfolgreich erstellen. Der Prozess, den ich zum Erstellen verwende, ist hier dokumentiert: https://github.com/petewarden4prs/tensorflow/tree/master/tensorflow/contrib/makefile#raspberry-pi
Anfangs habe ich den Fehler festgestellt, dass pthreading deaktiviert war ("Multithreading aktivieren, um std :: thread zu verwenden: Operation nicht zulässig"), als ich versuchte, die resultierende ausführbare Datei auf meinem Pi 3 auszuführen Jetzt stürzt das Programm scheinbar zufällig mit Segmentierungsfehlern ab. Wenn sie es in gdb ausführen, scheinen sie oft damit zu tun zu haben, dass free () mit schlechten Zeigern aufgerufen wird, und die Aufrufstapel scheinen beschädigt zu sein. Ich gehe also davon aus, dass eine Speicherinkongruenz vorliegt.
Hat jemand Vorschläge zu Dingen, mit denen ich versuchen kann, herauszufinden, was hier falsch läuft?
Hier sind einige weitere Details von meinem 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
Hier ist ein Beispiel für eine typische Sitzung in 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?)
quelle
Antworten:
Der einfachste Weg zu einer binär kompatiblen Cross-Kompilierung besteht darin, die von Raspbian-Entwicklern verwendete Toolchain zu installieren. Es kann hier gefunden werden . Es ist wichtig, diese Toolchain zu verwenden, wenn Sie den Kernel und die Treiber erstellen möchten, da Kernelobjekte eine perfekte ABI-Kompatibilität erfordern. Eine perfekte Kompatibilität schadet jedoch nicht, wenn Sie auch Userspace-Binärdateien erstellen.
Laut Dokumentation ist diese Toolchain mit dem aktuellen 32-Bit- und 64-Bit-Ubuntu kompatibel.
quelle
pure virtual method called
Beim Cross-Compilieren wurde eine Ausnahme angezeigt. @ JeremyBarnes 'Antwort hat bei mir nicht ganz funktioniert. Stattdessen habe ich verwendet:Erklärung :
Wie @JeremyBarnes hervorhob, müssen beide mit denselben
SYNC
Flags kompiliert werden, um die ABI-Kompatibilität Ihrer Anwendung mit dem installierten stdc ++ sicherzustellen .Auf Raspbian:
Ohne das Update auf
dockcross/linux-armv6
unddockcross/linux-armv7
:Mit dem Fix auf
dockcross/linux-armv6
unddockcross/linux-armv7
:quelle
FWIW, dies kann durch Hinzufügen
-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
zu den Compiler-Flags behoben werden .Warum? In /usr/include/c++/4.{8,9}/bits/concurrency.h hängt die Standardsperrrichtlinie von folgenden Definitionen ab:
Der ABI eines gemeinsam genutzten Zeigers hängt davon ab, wie diese Flags definiert sind, da er von einer Basisklasse erbt, die ein Standardvorlagenargument für die Sperrrichtlinie verwendet. Durch Ändern dieser Flags wird daher das Layout (da es das Basisklassenlayout ändert) der std :: shared_ptr <...> -Objekte in der Standard-C ++ - Bibliothek geändert.
In dem Compiler, der mit dem Pi geliefert wird, mit dem Raspbian erstellt wurde, werden sie wie folgt festgelegt:
Dies ist für den Pi 1 sinnvoll, aber eine große Schande für den Pi 3, der gerne atomare gemeinsame Zeiger verwenden kann.
Unter Ubuntu sind sie folgendermaßen eingerichtet:
Die obigen Befehlszeilenflags setzen sie auf den Standardwert auf dem Pi zurück.
Cross Compiling lohnt sich; Tensorflow baut auf einem bulligen Server bereits langsam auf. Es muss unglaublich lange dauern, um auf dem Pi aufzubauen!
quelle