I'm writing an event-based programming library for use on the BeagleBone Black and have encountered a strange error.
When I compile the exact same code with the exact same flags I receive the following errors on the ARM-based processor, but not when I run the code compiled for my x86 computer.
$ ./missionControl
pure virtual method called
pure virtual method called
pure virtual method called
terminate called recursively
terminate called recursively
Aborted
When I compile and run on my laptop, the program runs correctly.
This is the command I'm using to compile (ish, I'm using a Makefile, but both methods of compilation exhibit precisely the same behavior):
g++ -std=gnu++11 -pthread -O3 -D_GLIBCXX_USE_NANOSLEEP -o missionControl `find . -name *.cpp`
It doesn't matter whether I cross-compile with Ubuntu's arm-linux-gnueabi-g++
or the ARM-compatible g++
on the actual BeagleBone, I still get errors on ARM.
My question is this: What could be causing this error, and what can I do to try to find the source? Why would this happen on one processor architecture, but not another, for the same version of G++?
Thanks!
Here's a backtrace from the ARM processor's GDB:
#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?)
The problem turned out to be due to a bug in the ARM version of libstdc++ that runs on the BeagleBone. A small toy program that has no virtual functions at all causes the same error ("pure virtual function called") when std::thread is created.
I'm going to try to compile a custom version of gcc/libstdc++ 4.8 on the BeagleBone itself -- even if it takes a long time.
The pure virtual method called error occurs when you attempt to use dynamic dispatch to call a function that is pure virtual in a base before the derived type that implements it has been constructed or after it has already destructed.
The most common cause for this is if the base class attempts to call a virtual function that is pure at this level through the constructor or destructor. Other than that, as it has been pointed out in some comments, if you attempt to access a dead object, you might also run into this same issue.
Just attach a debugger to the program and see what virtual function is called and from where.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With